-%{ /* -*- c -*- emacs mode c */
- /*
+/* -*- c -*- emacs mode c */
+/* TREELANG Compiler parser.
- TREELANG Compiler parser.
+---------------------------------------------------------------------
- ---------------------------------------------------------------------
+Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
+In other words, you are welcome to use, share and improve this program.
+You are forbidden to forbid anyone else to use, share and improve
+what you give them. Help stamp out software-hoarding!
- In other words, you are welcome to use, share and improve this program.
- You are forbidden to forbid anyone else to use, share and improve
- what you give them. Help stamp out software-hoarding!
+---------------------------------------------------------------------
- ---------------------------------------------------------------------
+Written by Tim Josling 1999-2001, based in part on other parts of
+the GCC compiler. */
- Written by Tim Josling 1999-2001, based in part on other parts of
- the GCC compiler.
-
- */
-
- /*
-
- Grammar Conflicts
- *****************
-
- There are no conflicts in this grammar. Please keep it that way.
-
- */
+/* Grammar Conflicts
+ *****************
+ There are no conflicts in this grammar. Please keep it that way. */
+%{
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "diagnostic.h"
#include "timevar.h"
#include "treelang.h"
#include "treetree.h"
+#include "toplev.h"
#define YYDEBUG 1
#define YYPRINT(file, type, value) print_token (file, type, value)
#define YYERROR_VERBOSE YES
-/* My yylex routine used to intercept calls to flex generated code, to
+ /* My yylex routine used to intercept calls to flex generated code, to
record lex time. */
-int yylex (void);
-static inline int my_yylex(void);
-/* Call lex, but ensure time is charged to TV_LEX. */
-static inline int my_yylex ()
-{
- int res;
- timevar_push (TV_LEX);
- res = yylex ();
- timevar_pop (TV_LEX);
- return res;
-}
-#define yylex my_yylex
-
-extern int option_parser_trace;
-
-/* Local prototypes. */
+ int yylex (void);
+ static inline int my_yylex (void);
-static void yyerror (const char *error_message);
-int yyparse (void);
-void print_token (FILE * file, unsigned int type ATTRIBUTE_UNUSED, YYSTYPE value);
-static struct prod_token_parm_item *reverse_prod_list (struct prod_token_parm_item *old_first);
-static void ensure_not_void (unsigned int type, struct prod_token_parm_item* name);
-static int check_type_match (int type_num, struct prod_token_parm_item *exp);
-static int get_common_type (struct prod_token_parm_item *type1, struct prod_token_parm_item *type2);
-static struct prod_token_parm_item *make_integer_constant (struct prod_token_parm_item* value);
-static void set_storage (struct prod_token_parm_item *prod);
-
-/* File global variables. */
-
-static struct prod_token_parm_item *current_function=NULL;
+ /* Call lex, but ensure time is charged to TV_LEX. */
+ static inline int
+ my_yylex (void)
+ {
+ int res;
+ timevar_push (TV_LEX);
+ res = yylex ();
+ timevar_pop (TV_LEX);
+ return res;
+ }
+#define yylex my_yylex
+ extern int option_parser_trace;
+
+ /* Local prototypes. */
+ static void yyerror (const char *error_message);
+ int yyparse (void);
+ void print_token (FILE * file, unsigned int type ATTRIBUTE_UNUSED,
+ YYSTYPE value);
+ static struct prod_token_parm_item *reverse_prod_list
+ (struct prod_token_parm_item *old_first);
+ static void ensure_not_void (unsigned int type,
+ struct prod_token_parm_item* name);
+ static int check_type_match (int type_num, struct prod_token_parm_item *exp);
+ static int get_common_type (struct prod_token_parm_item *type1,
+ struct prod_token_parm_item *type2);
+ static struct prod_token_parm_item *make_integer_constant
+ (struct prod_token_parm_item* value);
+ static struct prod_token_parm_item *make_plus_expression
+ (struct prod_token_parm_item* tok, struct prod_token_parm_item* op1,
+ struct prod_token_parm_item* op2, int type_code, int prod_code);
+ static void set_storage (struct prod_token_parm_item *prod);
+
+ /* File global variables. */
+ static struct prod_token_parm_item *current_function = NULL;
%}
/* Not %raw - seems to have bugs. */
%%
file:
-/* Nil. */ {
+/* Nil. */ {
/* Nothing to do. */
}
|declarations {
SYMBOL_TABLE_NAME (prod) = tok;
EXPRESSION_TYPE (prod) = $2;
VAR_INIT (prod) = $4;
- NUMERIC_TYPE (prod) = NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod)));
+ NUMERIC_TYPE (prod) =
+ NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod)));
ensure_not_void (NUMERIC_TYPE (prod), tok);
if (insert_tree_name (prod))
{
if (VAR_INIT (prod))
{
- if (! ((struct prod_token_parm_item*)VAR_INIT (prod))->tp.pro.code)
- abort ();
- if (STORAGE_CLASS (prod) == EXTERNAL_REFERENCE_STORAGE)
- {
- fprintf (stderr, "%s:%i:%i: External reference variables may not have initial value\n", in_fname,
- tok->tp.tok.lineno, tok->tp.tok.charno);
- print_token (stderr, 0, tok);
- errorcount++;
- YYERROR;
- }
+ gcc_assert (((struct prod_token_parm_item*)VAR_INIT (prod))->tp.pro.code);
+ if (STORAGE_CLASS (prod) == EXTERNAL_REFERENCE_STORAGE)
+ {
+ error("%HExternal reference variable %q.*s has an initial value.",
+ &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
+ YYERROR;
+ VAR_INIT (prod) = NULL;
+ }
+
}
+
prod->tp.pro.code = tree_code_create_variable
(STORAGE_CLASS (prod),
((struct prod_token_parm_item*)SYMBOL_TABLE_NAME (prod))->tp.tok.chars,
((struct prod_token_parm_item*)SYMBOL_TABLE_NAME (prod))->tp.tok.length,
NUMERIC_TYPE (prod),
- VAR_INIT (prod)? ((struct prod_token_parm_item*)VAR_INIT (prod))->tp.pro.code:NULL,
- in_fname,
- tok->tp.tok.lineno);
- if (!prod->tp.pro.code)
- abort ();
+ VAR_INIT (prod) ?
+ ((struct prod_token_parm_item*)VAR_INIT (prod))->tp.pro.code : NULL,
+ tok->tp.tok.location);
+ gcc_assert (prod->tp.pro.code);
}
;
prod = make_production (PROD_VARIABLE_NAME, tok);
SYMBOL_TABLE_NAME (prod) = $2;
EXPRESSION_TYPE (prod) = $1;
- NUMERIC_TYPE (prod) = NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod)));
+ NUMERIC_TYPE (prod) =
+ NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod)));
ensure_not_void (NUMERIC_TYPE (prod), tok);
if (insert_tree_name (prod))
{
;
function_prototype:
-storage typename NAME LEFT_PARENTHESIS parameters RIGHT_PARENTHESIS SEMICOLON {
+storage typename NAME LEFT_PARENTHESIS parameters_opt RIGHT_PARENTHESIS SEMICOLON {
struct prod_token_parm_item* tok;
struct prod_token_parm_item *prod;
struct prod_token_parm_item *type;
prod = make_production (PROD_FUNCTION_NAME, $3);
SYMBOL_TABLE_NAME (prod) = $3;
EXPRESSION_TYPE (prod) = $2;
- NUMERIC_TYPE (prod) = NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod)));
+ NUMERIC_TYPE (prod) =
+ NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod)));
PARAMETERS (prod) = reverse_prod_list ($5);
insert_tree_name (prod);
STORAGE_CLASS_TOKEN (prod) = $1;
{
case STATIC_STORAGE:
case EXTERNAL_DEFINITION_STORAGE:
+ case EXTERNAL_REFERENCE_STORAGE:
break;
case AUTOMATIC_STORAGE:
- fprintf (stderr, "%s:%i:%i: A function cannot be automatic\n", in_fname,
- tok->tp.tok.lineno, tok->tp.tok.charno);
- print_token (stderr, 0, tok);
- errorcount++;
+ error ("%HFunction %q.*s cannot be automatic.",
+ &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
YYERROR;
break;
default:
- abort ();
+ gcc_unreachable ();
}
type = EXPRESSION_TYPE (prod);
/* Create a parameter list in a non-front end specific format. */
this_parm;
this_parm = this_parm->tp.pro.next)
{
- if (this_parm->category != production_category)
- abort ();
+ gcc_assert (this_parm->category == production_category);
this_parm_var = VARIABLE (this_parm);
- if (!this_parm_var)
- abort ();
- if (this_parm_var->category != production_category)
- abort ();
+
+ gcc_assert (this_parm_var);
+ gcc_assert (this_parm_var->category == production_category);
+ gcc_assert (this_parm_var->tp.pro.main_token);
+
this_parms = my_malloc (sizeof (struct prod_token_parm_item));
- if (!this_parm_var->tp.pro.main_token)
- abort ();
- this_parms->tp.par.variable_name = this_parm_var->tp.pro.main_token->tp.tok.chars;
+
+ this_parms->tp.par.variable_name =
+ this_parm_var->tp.pro.main_token->tp.tok.chars;
this_parms->category = parameter_category;
- this_parms->type = NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (this_parm_var)));
+ this_parms->type = NUMERIC_TYPE
+ (( (struct prod_token_parm_item*)EXPRESSION_TYPE (this_parm_var)));
if (last_parms)
{
last_parms->tp.par.next = this_parms;
}
FIRST_PARMS (prod) = first_parms;
- prod->tp.pro.code = tree_code_create_function_prototype
- (tok->tp.tok.chars, STORAGE_CLASS (prod), NUMERIC_TYPE (type),
- first_parms, in_fname, tok->tp.tok.lineno);
+ prod->tp.pro.code =
+ tree_code_create_function_prototype (tok->tp.tok.chars,
+ STORAGE_CLASS (prod),
+ NUMERIC_TYPE (type),
+ first_parms, tok->tp.tok.location);
+#ifdef ENABLE_CHECKING
+ /* Check all the parameters have code. */
+ for (this_parm = PARAMETERS (prod);
+ this_parm;
+ this_parm = this_parm->tp.pro.next)
+ {
+ gcc_assert ((struct prod_token_parm_item*)VARIABLE (this_parm));
+ gcc_assert (((struct prod_token_parm_item*)VARIABLE (this_parm))->tp.pro.code);
+ }
+#endif
}
;
struct prod_token_parm_item *proto;
struct prod_token_parm_item search_prod;
struct prod_token_parm_item* tok;
- struct prod_token_parm_item *this_parm;
tok = $1;
SYMBOL_TABLE_NAME ((&search_prod)) = tok;
search_prod.category = token_category;
current_function = proto = lookup_tree_name (&search_prod);
if (!proto)
{
- fprintf (stderr, "%s:%i:%i: Function prototype not found\n", in_fname,
- tok->tp.tok.lineno, tok->tp.tok.charno);
- print_token (stderr, 0, tok);
- errorcount++;
+ error ("%HNo prototype found for %q.*s", &tok->tp.tok.location,
+ tok->tp.tok.length, tok->tp.tok.chars);
YYERROR;
}
- if (!proto->tp.pro.code)
- abort ();
- tree_code_create_function_initial
- (proto->tp.pro.code, in_fname, tok->tp.tok.lineno,
- FIRST_PARMS (current_function));
- /* Check all the parameters have code. */
- for (this_parm = PARAMETERS (proto);
- this_parm;
- this_parm = this_parm->tp.pro.next)
- {
- if (! (struct prod_token_parm_item*)VARIABLE (this_parm))
- abort ();
- if (! (( (struct prod_token_parm_item*)VARIABLE (this_parm))->tp.pro.code))
- abort ();
- }
+ gcc_assert (proto->tp.pro.code);
+
+ tree_code_create_function_initial (proto->tp.pro.code, tok->tp.tok.location);
}
+
variable_defs_opt statements_opt RIGHT_BRACE {
struct prod_token_parm_item* tok;
tok = $1;
- tree_code_create_function_wrapup (in_fname, tok->tp.tok.lineno);
+ tree_code_create_function_wrapup (tok->tp.tok.location);
current_function = NULL;
}
;
variable_defs_opt:
-/* Nil. */ {
+/* Nil. */ {
$$ = 0;
}
|variable_defs {
;
statements_opt:
-/* Nil. */ {
+/* Nil. */ {
$$ = 0;
}
|statements {
}
;
+parameters_opt:
+/* Nothing to do. */ {
+ $$ = 0;
+}
+| parameters {
+ $$ = $1;
+}
+;
+
parameters:
parameter {
/* Nothing to do. */
expression SEMICOLON {
struct prod_token_parm_item *exp;
exp = $1;
- tree_code_output_expression_statement (exp->tp.pro.code, in_fname, exp->tp.pro.main_token->tp.tok.lineno);
+ tree_code_output_expression_statement (exp->tp.pro.code,
+ exp->tp.pro.main_token->tp.tok.location);
}
|return SEMICOLON {
/* Nothing to do. */
tok = $1;
exp = $3;
ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
- tree_code_if_start (exp->tp.pro.code, in_fname, tok->tp.tok.lineno);
+ tree_code_if_start (exp->tp.pro.code, tok->tp.tok.location);
}
-LEFT_BRACE statements_opt RIGHT_BRACE {
+LEFT_BRACE variable_defs_opt statements_opt RIGHT_BRACE {
/* Just let the statements flow. */
}
ELSE {
struct prod_token_parm_item* tok;
tok = $1;
- tree_code_if_else (in_fname, tok->tp.tok.lineno);
+ tree_code_if_else (tok->tp.tok.location);
}
-LEFT_BRACE statements_opt RIGHT_BRACE {
+LEFT_BRACE variable_defs_opt statements_opt RIGHT_BRACE {
struct prod_token_parm_item* tok;
- tok = $12;
- tree_code_if_end (in_fname, tok->tp.tok.lineno);
+ tok = $1;
+ tree_code_if_end (tok->tp.tok.location);
}
;
return:
tl_RETURN expression_opt {
struct prod_token_parm_item *type_prod;
- struct prod_token_parm_item* ret_tok;
- ret_tok = $1;
+ struct prod_token_parm_item *ret_tok = $1;
+ struct prod_token_parm_item *exp = $2;
+
type_prod = EXPRESSION_TYPE (current_function);
- if (NUMERIC_TYPE (type_prod) == VOID)
- if ($2 == NULL)
+ if (NUMERIC_TYPE (type_prod) == VOID_TYPE)
+ if (exp == NULL)
tree_code_generate_return (type_prod->tp.pro.code, NULL);
else
{
- fprintf (stderr, "%s:%i:%i: Redundant expression in return\n", in_fname,
- ret_tok->tp.tok.lineno, ret_tok->tp.tok.charno);
- print_token (stderr, 0, ret_tok);
- errorcount++;
+ warning (0, "%HRedundant expression in return.",
+ &ret_tok->tp.tok.location, ret_tok->tp.tok.length,
+ ret_tok->tp.tok.chars);
tree_code_generate_return (type_prod->tp.pro.code, NULL);
- }
+ }
else
- if ($2 == NULL)
- {
- fprintf (stderr, "%s:%i:%i: Expression missing in return\n", in_fname,
- ret_tok->tp.tok.lineno, ret_tok->tp.tok.charno);
- print_token (stderr, 0, ret_tok);
- errorcount++;
- }
+ if (exp == NULL)
+ error ("%HExpression missing in return.", &ret_tok->tp.tok.location);
else
{
- struct prod_token_parm_item *exp;
- exp = $2;
/* Check same type. */
- if (check_type_match (NUMERIC_TYPE (type_prod), $2))
+ if (check_type_match (NUMERIC_TYPE (type_prod), exp))
{
- if (!type_prod->tp.pro.code)
- abort ();
- if (!exp->tp.pro.code)
- abort ();
+ gcc_assert (type_prod->tp.pro.code);
+ gcc_assert (exp->tp.pro.code);
+
/* Generate the code. */
- tree_code_generate_return (type_prod->tp.pro.code, exp->tp.pro.code);
+ tree_code_generate_return (type_prod->tp.pro.code,
+ exp->tp.pro.code);
}
}
}
;
expression_opt:
-/* Nil. */ {
+/* Nil. */ {
$$ = 0;
}
|expression {
struct prod_token_parm_item *exp;
exp = $1;
- if (!exp->tp.pro.code)
- abort ();
+ gcc_assert (exp->tp.pro.code);
$$ = $1;
}
$$ = $1;
}
|expression tl_PLUS expression {
- struct prod_token_parm_item* tok;
- struct prod_token_parm_item *prod;
- struct prod_token_parm_item *op1;
- struct prod_token_parm_item *op2;
- tree type;
-
- op1 = $1;
- op2 = $3;
- tok = $2;
- ensure_not_void (NUMERIC_TYPE (op1), op1->tp.pro.main_token);
- ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
- prod = make_production (PROD_PLUS_EXPRESSION, tok);
- NUMERIC_TYPE (prod) = get_common_type (op1, op2);
- if (!NUMERIC_TYPE (prod))
+ struct prod_token_parm_item *tok = $2;
+ struct prod_token_parm_item *op1 = $1;
+ struct prod_token_parm_item *op2 = $3;
+ int type_code = get_common_type (op1, op2);
+ if (!type_code)
YYERROR;
- else
- {
- type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
- if (!type)
- abort ();
- OP1 (prod) = $1;
- OP2 (prod) = $3;
-
- prod->tp.pro.code = tree_code_get_expression
- (EXP_PLUS, type, op1->tp.pro.code, op2->tp.pro.code, NULL);
- }
- $$ = prod;
+ $$ = make_plus_expression (tok, op1, op2, type_code, EXP_PLUS);
}
|expression tl_MINUS expression %prec tl_PLUS {
- struct prod_token_parm_item* tok;
- struct prod_token_parm_item *prod;
- struct prod_token_parm_item *op1;
- struct prod_token_parm_item *op2;
- tree type;
-
- op1 = $1;
- op2 = $3;
- ensure_not_void (NUMERIC_TYPE (op1), op1->tp.pro.main_token);
- ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
- tok = $2;
- prod = make_production (PROD_PLUS_EXPRESSION, tok);
- NUMERIC_TYPE (prod) = get_common_type (op1, op2);
- if (!NUMERIC_TYPE (prod))
+ struct prod_token_parm_item *tok = $2;
+ struct prod_token_parm_item *op1 = $1;
+ struct prod_token_parm_item *op2 = $3;
+ int type_code = get_common_type (op1, op2);
+ if (!type_code)
YYERROR;
- else
- {
- type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
- if (!type)
- abort ();
- OP1 (prod) = $1;
- OP2 (prod) = $3;
-
- prod->tp.pro.code = tree_code_get_expression (EXP_MINUS,
- type, op1->tp.pro.code, op2->tp.pro.code, NULL);
- }
- $$ = prod;
+ $$ = make_plus_expression (tok, op1, op2, type_code, EXP_MINUS);
}
|expression EQUALS expression {
- struct prod_token_parm_item* tok;
- struct prod_token_parm_item *prod;
- struct prod_token_parm_item *op1;
- struct prod_token_parm_item *op2;
- tree type;
-
- op1 = $1;
- op2 = $3;
- ensure_not_void (NUMERIC_TYPE (op1), op1->tp.pro.main_token);
- ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
- tok = $2;
- prod = make_production (PROD_PLUS_EXPRESSION, tok);
- NUMERIC_TYPE (prod) = SIGNED_INT;
- if (!NUMERIC_TYPE (prod))
+ struct prod_token_parm_item *tok = $2;
+ struct prod_token_parm_item *op1 = $1;
+ struct prod_token_parm_item *op2 = $3;
+ int type_code = NUMERIC_TYPE (op1);
+ if (!type_code)
YYERROR;
- else
- {
- type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
- if (!type)
- abort ();
- OP1 (prod) = $1;
- OP2 (prod) = $3;
-
- prod->tp.pro.code = tree_code_get_expression (EXP_EQUALS,
- type, op1->tp.pro.code, op2->tp.pro.code, NULL);
- }
- $$ = prod;
+ $$ = make_plus_expression
+ (tok, op1, op2, type_code, EXP_EQUALS);
}
|variable_ref ASSIGN expression {
- struct prod_token_parm_item* tok;
- struct prod_token_parm_item *prod;
- struct prod_token_parm_item *op1;
- struct prod_token_parm_item *op2;
- tree type;
-
- op1 = $1;
- op2 = $3;
- tok = $2;
- ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
- prod = make_production (PROD_ASSIGN_EXPRESSION, tok);
- NUMERIC_TYPE (prod) = NUMERIC_TYPE (op1);
- if (!NUMERIC_TYPE (prod))
+ struct prod_token_parm_item *tok = $2;
+ struct prod_token_parm_item *op1 = $1;
+ struct prod_token_parm_item *op2 = $3;
+ int type_code = NUMERIC_TYPE (op1);
+ if (!type_code)
YYERROR;
- else
- {
- type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
- if (!type)
- abort ();
- OP1 (prod) = $1;
- OP2 (prod) = $3;
- prod->tp.pro.code = tree_code_get_expression (EXP_ASSIGN,
- type, op1->tp.pro.code, op2->tp.pro.code, NULL);
- }
- $$ = prod;
+ $$ = make_plus_expression
+ (tok, op1, op2, type_code, EXP_ASSIGN);
}
|function_invocation {
$$ = $1;
;
function_invocation:
-NAME LEFT_PARENTHESIS expressions_with_commas RIGHT_PARENTHESIS {
+NAME LEFT_PARENTHESIS expressions_with_commas_opt RIGHT_PARENTHESIS {
struct prod_token_parm_item *prod;
struct prod_token_parm_item* tok;
struct prod_token_parm_item search_prod;
proto = lookup_tree_name (&search_prod);
if (!proto)
{
- fprintf (stderr, "%s:%i:%i: Function prototype not found\n", in_fname,
- tok->tp.tok.lineno, tok->tp.tok.charno);
- print_token (stderr, 0, tok);
- errorcount++;
+ error ("%HFunction prototype not found for %q.*%s.",
+ &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
YYERROR;
}
EXPRESSION_TYPE (prod) = EXPRESSION_TYPE (proto);
if (exp_count != exp_proto_count)
{
- fprintf (stderr, "%s:%i:%i: expression count mismatch with prototype\n", in_fname,
- tok->tp.tok.lineno, tok->tp.tok.charno);
- print_token (stderr, 0, tok);
- errorcount++;
+ error ("%HExpression count mismatch %q.*s with prototype.",
+ &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
YYERROR;
}
parms = tree_code_init_parameters ();
for (exp_proto = PARAMETERS (proto), exp = PARAMETERS (prod);
exp_proto;
exp = exp->tp.pro.next, exp_proto = exp_proto->tp.pro.next)
- {
- if (!exp)
- abort ();
- if (!exp_proto)
- abort ();
- if (!exp->tp.pro.code)
- abort ();
- var = VARIABLE (exp_proto);
- if (!var)
- abort ();
- if (!var->tp.pro.code)
- abort ();
- parms = tree_code_add_parameter (parms, var->tp.pro.code, exp->tp.pro.code);
- }
- type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
- prod->tp.pro.code = tree_code_get_expression
- (EXP_FUNCTION_INVOCATION, type, proto->tp.pro.code, parms, NULL);
+ {
+ gcc_assert (exp);
+ gcc_assert (exp_proto);
+ gcc_assert (exp->tp.pro.code);
+
+ var = VARIABLE (exp_proto);
+
+ gcc_assert (var);
+ gcc_assert (var->tp.pro.code);
+
+ parms = tree_code_add_parameter (parms, var->tp.pro.code,
+ exp->tp.pro.code);
+ }
+ type = tree_code_get_type (NUMERIC_TYPE (prod));
+ prod->tp.pro.code = tree_code_get_expression (EXP_FUNCTION_INVOCATION, type,
+ proto->tp.pro.code, parms,
+ NULL, tok->tp.tok.location);
$$ = prod;
}
;
+expressions_with_commas_opt:
+/* Nil. */ {
+$$ = 0
+}
+|expressions_with_commas { $$ = $1 }
+;
+
expressions_with_commas:
expression {
struct prod_token_parm_item *exp;
symbol_table_entry = lookup_tree_name (&search_prod);
if (!symbol_table_entry)
{
- fprintf (stderr, "%s:%i:%i: Variable referred to but not defined\n", in_fname,
- tok->tp.tok.lineno, tok->tp.tok.charno);
- print_token (stderr, 0, tok);
- errorcount++;
+ error ("%HVariable %q.*s not defined.",
+ &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
YYERROR;
}
prod = make_production (PROD_VARIABLE_REFERENCE_EXPRESSION, tok);
NUMERIC_TYPE (prod) = NUMERIC_TYPE (symbol_table_entry);
- type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
+ type = tree_code_get_type (NUMERIC_TYPE (prod));
if (!NUMERIC_TYPE (prod))
YYERROR;
OP1 (prod) = $1;
- prod->tp.pro.code = tree_code_get_expression (EXP_REFERENCE, type,
- symbol_table_entry->tp.pro.code, NULL, NULL);
+ prod->tp.pro.code =
+ tree_code_get_expression (EXP_REFERENCE, type,
+ symbol_table_entry->tp.pro.code, NULL, NULL,
+ tok->tp.tok.location);
$$ = prod;
}
;
init_opt:
-/* Nil. */ {
+/* Nil. */ {
$$ = 0;
}
|init {
- /* Nothing to do. */
+ /* Pass the initialization value up. */
+ $$ = $1;
};
init:
ASSIGN init_element {
+ $$ = $2;
}
;
unsigned int ix;
tok = value;
- fprintf (file, "%d \"", tok->tp.tok.lineno);
+ fprintf (file, "%d \"", LOCATION_LINE (tok->tp.tok.location));
for (ix = 0; ix < tok->tp.tok.length; ix++)
fprintf (file, "%c", tok->tp.tok.chars[ix]);
+
fprintf (file, "\"");
}
/* Output a message ERROR_MESSAGE from the parser. */
-void
+static void
yyerror (const char *error_message)
{
struct prod_token_parm_item *tok;
-
+
tok = yylval;
if (tok)
- {
- fprintf (stderr, "%s:%i:%i: %s\n", in_fname, tok->tp.tok.lineno, tok->tp.tok.charno, error_message);
- print_token (stderr, 0, tok);
- }
+ error ("%H%s", &tok->tp.tok.location, error_message);
else
- fprintf (stderr, "%s\n", error_message);
-
- errorcount++;
-
+ error ("%s", error_message);
}
/* Reverse the order of a token list, linked by parse_next, old first
while (current)
{
- if (current->category != production_category)
- abort ();
+ gcc_assert (current->category == production_category);
+
next = current->tp.pro.next;
current->tp.pro.next = prev;
prev = current;
static void
ensure_not_void (unsigned int type, struct prod_token_parm_item* name)
{
- if (type == VOID)
- {
- fprintf (stderr, "%s:%i:%i: Type must not be void in this context\n", in_fname,
- name->tp.tok.lineno, name->tp.tok.charno);
- print_token (stderr, 0, name);
- errorcount++;
- }
+ if (type == VOID_TYPE)
+ error ("%HType must not be void in this context.",
+ &name->tp.tok.location);
}
/* Check TYPE1 and TYPE2 which are integral types. Return the lowest
common type (min is signed int). */
static int
-get_common_type (struct prod_token_parm_item *type1, struct prod_token_parm_item *type2)
+get_common_type (struct prod_token_parm_item *type1,
+ struct prod_token_parm_item *type2)
{
if (NUMERIC_TYPE (type1) == UNSIGNED_INT)
return UNSIGNED_INT;
case UNSIGNED_CHAR:
return 1;
- case VOID:
- abort ();
-
+ case VOID_TYPE:
default:
- abort ();
+ gcc_unreachable ();
}
break;
- case VOID:
- abort ();
-
+ case VOID_TYPE:
default:
- abort ();
+ gcc_unreachable ();
}
}
struct prod_token_parm_item *prod;
tok = value;
prod = make_production (PROD_INTEGER_CONSTANT, tok);
- if ((tok->tp.tok.chars[0] == (unsigned char)'-')|| (tok->tp.tok.chars[0] == (unsigned char)'+'))
+ if ((tok->tp.tok.chars[0] == (unsigned char)'-')
+ || (tok->tp.tok.chars[0] == (unsigned char)'+'))
NUMERIC_TYPE (prod) = SIGNED_INT;
else
NUMERIC_TYPE (prod) = UNSIGNED_INT;
- prod->tp.pro.code = tree_code_get_integer_value (tok->tp.tok.chars, tok->tp.tok.length);
+ prod->tp.pro.code = tree_code_get_integer_value (tok->tp.tok.chars,
+ tok->tp.tok.length);
+ return prod;
+}
+
+
+/* Build a PROD_PLUS_EXPRESSION. This is uses for PLUS, MINUS, ASSIGN
+ and EQUALS expressions. */
+
+static struct prod_token_parm_item *
+make_plus_expression (struct prod_token_parm_item* tok,
+ struct prod_token_parm_item* op1,
+ struct prod_token_parm_item* op2,
+ int type_code, int prod_code)
+{
+ struct prod_token_parm_item *prod;
+ tree type;
+
+ ensure_not_void (NUMERIC_TYPE (op1), op1->tp.pro.main_token);
+ ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
+
+ prod = make_production (PROD_PLUS_EXPRESSION, tok);
+
+ NUMERIC_TYPE (prod) = type_code;
+ type = tree_code_get_type (type_code);
+
+ gcc_assert (type);
+
+ OP1 (prod) = op1;
+ OP2 (prod) = op2;
+
+ prod->tp.pro.code = tree_code_get_expression (prod_code, type,
+ op1->tp.pro.code,
+ op2->tp.pro.code, NULL,
+ tok->tp.tok.location);
+
return prod;
}
+
/* Set STORAGE_CLASS in PROD according to CLASS_TOKEN. */
static void
break;
default:
- abort ();
+ gcc_unreachable ();
}
}
if (option_parser_trace)
yydebug = 1;
}
+
+#ifdef __XGETTEXT__
+/* Depending on the version of Bison used to compile this grammar,
+ it may issue generic diagnostics spelled "syntax error" or
+ "parse error". To prevent this from changing the translation
+ template randomly, we list all the variants of this particular
+ diagnostic here. Translators: there is no fine distinction
+ between diagnostics with "syntax error" in them, and diagnostics
+ with "parse error" in them. It's okay to give them both the same
+ translation. */
+const char d1[] = N_("syntax error");
+const char d2[] = N_("parse error");
+const char d3[] = N_("syntax error; also virtual memory exhausted");
+const char d4[] = N_("parse error; also virtual memory exhausted");
+const char d5[] = N_("syntax error: cannot back up");
+const char d6[] = N_("parse error: cannot back up");
+#endif