1198 lines
26 KiB
Plaintext
1198 lines
26 KiB
Plaintext
/* Parser grammar for quick source code scan of Java(TM) language programs.
|
||
Copyright (C) 1998, 1999 Free Software Foundation, Inc.
|
||
Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
|
||
|
||
This file is part of GNU CC.
|
||
|
||
GNU CC 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.
|
||
|
||
GNU CC 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 GNU CC; see the file COPYING. If not, write to
|
||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||
Boston, MA 02111-1307, USA.
|
||
|
||
Java and all Java-based marks are trademarks or registered trademarks
|
||
of Sun Microsystems, Inc. in the United States and other countries.
|
||
The Free Software Foundation is independent of Sun Microsystems, Inc. */
|
||
|
||
/* This file parses Java source code. Action can be further completed
|
||
to achieve a desired behavior. This file isn't part of the Java
|
||
language gcc front end.
|
||
|
||
The grammar conforms to the Java grammar described in "The Java(TM)
|
||
Language Specification. J. Gosling, B. Joy, G. Steele. Addison Wesley
|
||
1996, ISBN 0-201-63451-1"
|
||
|
||
Some rules have been modified to support JDK1.1 inner classes
|
||
definitions and other extensions. */
|
||
|
||
%{
|
||
#define JC1_LITE
|
||
|
||
#include "config.h"
|
||
#include "system.h"
|
||
|
||
#include "obstack.h"
|
||
#include "toplev.h"
|
||
|
||
extern char *input_filename;
|
||
extern FILE *finput, *out;
|
||
|
||
/* Obstack for the lexer. */
|
||
struct obstack temporary_obstack;
|
||
|
||
/* The current parser context. */
|
||
static struct parser_ctxt *ctxp;
|
||
|
||
/* Error and warning counts, current line number, because they're used
|
||
elsewhere */
|
||
int java_error_count;
|
||
int java_warning_count;
|
||
int lineno;
|
||
|
||
/* Tweak default rules when necessary. */
|
||
static int absorber;
|
||
#define USE_ABSORBER absorber = 0
|
||
|
||
/* Keep track of the current class name and package name. */
|
||
static char *current_class;
|
||
static char *package_name;
|
||
|
||
/* Keep track of whether things have be listed before. */
|
||
static int previous_output;
|
||
|
||
/* Record modifier uses */
|
||
static int modifier_value;
|
||
|
||
/* Keep track of number of bracket pairs after a variable declarator
|
||
id. */
|
||
static int bracket_count;
|
||
|
||
/* Record a method declaration */
|
||
struct method_declarator {
|
||
char *method_name;
|
||
char *args;
|
||
};
|
||
#define NEW_METHOD_DECLARATOR(D,N,A) \
|
||
{ \
|
||
(D) = \
|
||
(struct method_declarator *)xmalloc (sizeof (struct method_declarator)); \
|
||
(D)->method_name = (N); \
|
||
(D)->args = (A); \
|
||
}
|
||
|
||
/* Two actions for this grammar */
|
||
static void report_class_declaration PROTO ((char *));
|
||
static void report_main_declaration PROTO ((struct method_declarator *));
|
||
|
||
#include "lex.h"
|
||
#include "parse.h"
|
||
%}
|
||
|
||
%union {
|
||
char *node;
|
||
struct method_declarator *declarator;
|
||
int value; /* For modifiers */
|
||
}
|
||
|
||
%pure_parser
|
||
|
||
/* Things defined here have to match the order of what's in the
|
||
binop_lookup table. */
|
||
|
||
%token PLUS_TK MINUS_TK MULT_TK DIV_TK REM_TK
|
||
%token LS_TK SRS_TK ZRS_TK
|
||
%token AND_TK XOR_TK OR_TK
|
||
%token BOOL_AND_TK BOOL_OR_TK
|
||
%token EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
|
||
|
||
/* This maps to the same binop_lookup entry than the token above */
|
||
|
||
%token PLUS_ASSIGN_TK MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
|
||
%token REM_ASSIGN_TK
|
||
%token LS_ASSIGN_TK SRS_ASSIGN_TK ZRS_ASSIGN_TK
|
||
%token AND_ASSIGN_TK XOR_ASSIGN_TK OR_ASSIGN_TK
|
||
|
||
|
||
/* Modifier TOKEN have to be kept in this order. Don't scramble it */
|
||
|
||
%token PUBLIC_TK PRIVATE_TK PROTECTED_TK
|
||
%token STATIC_TK FINAL_TK SYNCHRONIZED_TK
|
||
%token VOLATILE_TK TRANSIENT_TK NATIVE_TK
|
||
%token PAD_TK ABSTRACT_TK MODIFIER_TK
|
||
|
||
/* Keep those two in order, too */
|
||
%token DECR_TK INCR_TK
|
||
|
||
/* From now one, things can be in any order */
|
||
|
||
%token DEFAULT_TK IF_TK THROW_TK
|
||
%token BOOLEAN_TK DO_TK IMPLEMENTS_TK
|
||
%token THROWS_TK BREAK_TK IMPORT_TK
|
||
%token ELSE_TK INSTANCEOF_TK RETURN_TK
|
||
%token VOID_TK CATCH_TK INTERFACE_TK
|
||
%token CASE_TK EXTENDS_TK FINALLY_TK
|
||
%token SUPER_TK WHILE_TK CLASS_TK
|
||
%token SWITCH_TK CONST_TK TRY_TK
|
||
%token FOR_TK NEW_TK CONTINUE_TK
|
||
%token GOTO_TK PACKAGE_TK THIS_TK
|
||
|
||
%token BYTE_TK SHORT_TK INT_TK LONG_TK
|
||
%token CHAR_TK INTEGRAL_TK
|
||
|
||
%token FLOAT_TK DOUBLE_TK FP_TK
|
||
|
||
%token ID_TK
|
||
|
||
%token REL_QM_TK REL_CL_TK NOT_TK NEG_TK
|
||
|
||
%token ASSIGN_ANY_TK ASSIGN_TK
|
||
%token OP_TK CP_TK OCB_TK CCB_TK OSB_TK CSB_TK SC_TK C_TK DOT_TK
|
||
|
||
%token STRING_LIT_TK CHAR_LIT_TK INT_LIT_TK FP_LIT_TK
|
||
%token TRUE_TK FALSE_TK BOOL_LIT_TK NULL_TK
|
||
|
||
%type <node> ID_TK identifier name simple_name qualified_name type
|
||
primitive_type reference_type array_type formal_parameter_list
|
||
formal_parameter class_or_interface_type class_type interface_type
|
||
%type <declarator> method_declarator
|
||
%type <value> MODIFIER_TK
|
||
|
||
%%
|
||
/* 19.2 Production from 2.3: The Syntactic Grammar */
|
||
goal:
|
||
compilation_unit
|
||
;
|
||
|
||
/* 19.3 Productions from 3: Lexical structure */
|
||
literal:
|
||
INT_LIT_TK
|
||
| FP_LIT_TK
|
||
| BOOL_LIT_TK
|
||
| CHAR_LIT_TK
|
||
| STRING_LIT_TK
|
||
| NULL_TK
|
||
;
|
||
|
||
/* 19.4 Productions from 4: Types, Values and Variables */
|
||
type:
|
||
primitive_type
|
||
| reference_type
|
||
;
|
||
|
||
primitive_type:
|
||
INTEGRAL_TK
|
||
{
|
||
/* use preset global here. FIXME */
|
||
$$ = xstrdup ("int");
|
||
}
|
||
| FP_TK
|
||
{
|
||
/* use preset global here. FIXME */
|
||
$$ = xstrdup ("double");
|
||
}
|
||
| BOOLEAN_TK
|
||
{
|
||
/* use preset global here. FIXME */
|
||
$$ = xstrdup ("boolean");
|
||
}
|
||
;
|
||
|
||
reference_type:
|
||
class_or_interface_type
|
||
| array_type
|
||
;
|
||
|
||
class_or_interface_type:
|
||
name
|
||
;
|
||
|
||
class_type:
|
||
class_or_interface_type /* Default rule */
|
||
;
|
||
|
||
interface_type:
|
||
class_or_interface_type
|
||
;
|
||
|
||
array_type:
|
||
primitive_type OSB_TK CSB_TK
|
||
| name OSB_TK CSB_TK
|
||
{
|
||
char *n = xmalloc (strlen ($1)+2);
|
||
n [0] = '[';
|
||
strcpy (n+1, $1);
|
||
$$ = n;
|
||
}
|
||
| array_type OSB_TK CSB_TK
|
||
{
|
||
char *n = xmalloc (strlen ($1)+2);
|
||
n [0] = '[';
|
||
strcpy (n+1, $1);
|
||
$$ = n;
|
||
}
|
||
;
|
||
|
||
/* 19.5 Productions from 6: Names */
|
||
name:
|
||
simple_name /* Default rule */
|
||
| qualified_name /* Default rule */
|
||
;
|
||
|
||
simple_name:
|
||
identifier /* Default rule */
|
||
;
|
||
|
||
qualified_name:
|
||
name DOT_TK identifier
|
||
{
|
||
char *n = xmalloc (strlen ($1)+strlen ($3)+2);
|
||
sprintf (n, "%s.%s", $1, $3);
|
||
$$ = n;
|
||
}
|
||
;
|
||
|
||
identifier:
|
||
ID_TK
|
||
;
|
||
|
||
/* 19.6: Production from 7: Packages */
|
||
compilation_unit:
|
||
| package_declaration
|
||
| import_declarations
|
||
| type_declarations
|
||
| package_declaration import_declarations
|
||
| package_declaration type_declarations
|
||
| import_declarations type_declarations
|
||
| package_declaration import_declarations type_declarations
|
||
;
|
||
|
||
import_declarations:
|
||
import_declaration
|
||
| import_declarations import_declaration
|
||
;
|
||
|
||
type_declarations:
|
||
type_declaration
|
||
| type_declarations type_declaration
|
||
;
|
||
|
||
package_declaration:
|
||
PACKAGE_TK name SC_TK
|
||
{ package_name = $2; }
|
||
;
|
||
|
||
import_declaration:
|
||
single_type_import_declaration
|
||
| type_import_on_demand_declaration
|
||
;
|
||
|
||
single_type_import_declaration:
|
||
IMPORT_TK name SC_TK
|
||
;
|
||
|
||
type_import_on_demand_declaration:
|
||
IMPORT_TK name DOT_TK MULT_TK SC_TK
|
||
;
|
||
|
||
type_declaration:
|
||
class_declaration
|
||
| interface_declaration
|
||
| SC_TK
|
||
;
|
||
|
||
/* 19.7 Shortened from the original:
|
||
modifiers: modifier | modifiers modifier
|
||
modifier: any of public... */
|
||
modifiers:
|
||
MODIFIER_TK
|
||
{
|
||
if ($1 == PUBLIC_TK)
|
||
modifier_value++;
|
||
if ($1 == STATIC_TK)
|
||
modifier_value++;
|
||
USE_ABSORBER;
|
||
}
|
||
| modifiers MODIFIER_TK
|
||
{
|
||
if ($2 == PUBLIC_TK)
|
||
modifier_value++;
|
||
if ($2 == STATIC_TK)
|
||
modifier_value++;
|
||
USE_ABSORBER;
|
||
}
|
||
;
|
||
|
||
/* 19.8.1 Production from $8.1: Class Declaration */
|
||
class_declaration:
|
||
modifiers CLASS_TK identifier super interfaces
|
||
{
|
||
report_class_declaration($3);
|
||
modifier_value = 0;
|
||
}
|
||
class_body
|
||
| CLASS_TK identifier super interfaces
|
||
{ report_class_declaration($2); }
|
||
class_body
|
||
;
|
||
|
||
super:
|
||
| EXTENDS_TK class_type
|
||
;
|
||
|
||
interfaces:
|
||
| IMPLEMENTS_TK interface_type_list
|
||
;
|
||
|
||
interface_type_list:
|
||
interface_type
|
||
{ USE_ABSORBER; }
|
||
| interface_type_list C_TK interface_type
|
||
{ USE_ABSORBER; }
|
||
;
|
||
|
||
class_body:
|
||
OCB_TK CCB_TK
|
||
| OCB_TK class_body_declarations CCB_TK
|
||
;
|
||
|
||
class_body_declarations:
|
||
class_body_declaration
|
||
| class_body_declarations class_body_declaration
|
||
;
|
||
|
||
class_body_declaration:
|
||
class_member_declaration
|
||
| static_initializer
|
||
| constructor_declaration
|
||
| block /* Added, JDK1.1, instance initializer */
|
||
;
|
||
|
||
class_member_declaration:
|
||
field_declaration
|
||
| method_declaration
|
||
| class_declaration /* Added, JDK1.1 inner classes */
|
||
| interface_declaration /* Added, JDK1.1 inner classes */
|
||
;
|
||
|
||
/* 19.8.2 Productions from 8.3: Field Declarations */
|
||
field_declaration:
|
||
type variable_declarators SC_TK
|
||
{ USE_ABSORBER; }
|
||
| modifiers type variable_declarators SC_TK
|
||
{ modifier_value = 0; }
|
||
;
|
||
|
||
variable_declarators:
|
||
/* Should we use build_decl_list () instead ? FIXME */
|
||
variable_declarator /* Default rule */
|
||
| variable_declarators C_TK variable_declarator
|
||
;
|
||
|
||
variable_declarator:
|
||
variable_declarator_id
|
||
| variable_declarator_id ASSIGN_TK variable_initializer
|
||
;
|
||
|
||
variable_declarator_id:
|
||
identifier
|
||
{ bracket_count = 0; USE_ABSORBER; }
|
||
| variable_declarator_id OSB_TK CSB_TK
|
||
{ ++bracket_count; }
|
||
;
|
||
|
||
variable_initializer:
|
||
expression
|
||
| array_initializer
|
||
;
|
||
|
||
/* 19.8.3 Productions from 8.4: Method Declarations */
|
||
method_declaration:
|
||
method_header method_body
|
||
;
|
||
|
||
method_header:
|
||
type method_declarator throws
|
||
{ USE_ABSORBER; }
|
||
| VOID_TK method_declarator throws
|
||
| modifiers type method_declarator throws
|
||
{ modifier_value = 0; }
|
||
| modifiers VOID_TK method_declarator throws
|
||
{
|
||
report_main_declaration ($3);
|
||
modifier_value = 0;
|
||
}
|
||
;
|
||
|
||
method_declarator:
|
||
identifier OP_TK CP_TK
|
||
{
|
||
struct method_declarator *d;
|
||
NEW_METHOD_DECLARATOR (d, $1, NULL);
|
||
$$ = d;
|
||
}
|
||
| identifier OP_TK formal_parameter_list CP_TK
|
||
{
|
||
struct method_declarator *d;
|
||
NEW_METHOD_DECLARATOR (d, $1, $3);
|
||
$$ = d;
|
||
}
|
||
| method_declarator OSB_TK CSB_TK
|
||
;
|
||
|
||
formal_parameter_list:
|
||
formal_parameter
|
||
| formal_parameter_list C_TK formal_parameter
|
||
{
|
||
char *n = xmalloc (strlen ($1)+strlen($3)+2);
|
||
sprintf (n, "%s,%s", $1, $3);
|
||
$$ = n;
|
||
}
|
||
;
|
||
|
||
formal_parameter:
|
||
type variable_declarator_id
|
||
{
|
||
USE_ABSORBER;
|
||
if (bracket_count)
|
||
{
|
||
int i;
|
||
char *n = xmalloc (bracket_count + 1 + strlen ($$));
|
||
for (i = 0; i < bracket_count; ++i)
|
||
n[i] = '[';
|
||
strcpy (n + bracket_count, $$);
|
||
$$ = n;
|
||
}
|
||
else
|
||
$$ = $1;
|
||
}
|
||
| modifiers type variable_declarator_id /* Added, JDK1.1 final locals */
|
||
{
|
||
if (bracket_count)
|
||
{
|
||
int i;
|
||
char *n = xmalloc (bracket_count + 1 + strlen ($$));
|
||
for (i = 0; i < bracket_count; ++i)
|
||
n[i] = '[';
|
||
strcpy (n + bracket_count, $$);
|
||
$$ = n;
|
||
}
|
||
else
|
||
$$ = $2;
|
||
}
|
||
;
|
||
|
||
throws:
|
||
| THROWS_TK class_type_list
|
||
;
|
||
|
||
class_type_list:
|
||
class_type
|
||
{ USE_ABSORBER; }
|
||
| class_type_list C_TK class_type
|
||
{ USE_ABSORBER; }
|
||
;
|
||
|
||
method_body:
|
||
block
|
||
| block SC_TK
|
||
| SC_TK
|
||
;
|
||
|
||
/* 19.8.4 Productions from 8.5: Static Initializers */
|
||
static_initializer:
|
||
static block
|
||
| static block SC_TK /* Shouldn't be here. FIXME */
|
||
;
|
||
|
||
static: /* Test lval.sub_token here */
|
||
MODIFIER_TK
|
||
{ USE_ABSORBER; }
|
||
;
|
||
|
||
/* 19.8.5 Productions from 8.6: Constructor Declarations */
|
||
/* NOTE FOR FURTHER WORK ON CONSTRUCTORS:
|
||
- If a forbidded modifier is found, the the error is either the use of
|
||
a forbidded modifier for a constructor OR bogus attempt to declare a
|
||
method without having specified the return type. FIXME */
|
||
constructor_declaration:
|
||
constructor_declarator throws constructor_body
|
||
| modifiers constructor_declarator throws constructor_body
|
||
{ modifier_value = 0; }
|
||
/* extra SC_TK, FIXME */
|
||
| constructor_declarator throws constructor_body SC_TK
|
||
/* extra SC_TK, FIXME */
|
||
| modifiers constructor_declarator throws constructor_body SC_TK
|
||
{ modifier_value = 0; }
|
||
/* I'm not happy with the SC_TK addition. It isn't in the grammer and should
|
||
probably be matched by and empty statement. But it doesn't work. FIXME */
|
||
;
|
||
|
||
constructor_declarator:
|
||
simple_name OP_TK CP_TK
|
||
{ USE_ABSORBER; }
|
||
| simple_name OP_TK formal_parameter_list CP_TK
|
||
{ USE_ABSORBER; }
|
||
;
|
||
|
||
constructor_body:
|
||
OCB_TK CCB_TK
|
||
| OCB_TK explicit_constructor_invocation CCB_TK
|
||
| OCB_TK block_statements CCB_TK
|
||
| OCB_TK explicit_constructor_invocation block_statements CCB_TK
|
||
;
|
||
|
||
/* Error recovery for that rule moved down expression_statement: rule. */
|
||
explicit_constructor_invocation:
|
||
this_or_super OP_TK CP_TK SC_TK
|
||
| this_or_super OP_TK argument_list CP_TK SC_TK
|
||
/* Added, JDK1.1 inner classes. Modified because the rule
|
||
'primary' couldn't work. */
|
||
| name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
|
||
{ USE_ABSORBER; }
|
||
| name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
|
||
{ USE_ABSORBER; }
|
||
;
|
||
|
||
this_or_super: /* Added, simplifies error diagnostics */
|
||
THIS_TK
|
||
| SUPER_TK
|
||
;
|
||
|
||
/* 19.9 Productions from 9: Interfaces */
|
||
/* 19.9.1 Productions from 9.1: Interfaces Declarations */
|
||
interface_declaration:
|
||
INTERFACE_TK identifier interface_body
|
||
{ report_class_declaration ($2); modifier_value = 0; }
|
||
| modifiers INTERFACE_TK identifier interface_body
|
||
{ report_class_declaration ($3); modifier_value = 0; }
|
||
| INTERFACE_TK identifier extends_interfaces interface_body
|
||
{ report_class_declaration ($2); modifier_value = 0; }
|
||
| modifiers INTERFACE_TK identifier extends_interfaces interface_body
|
||
{ report_class_declaration ($3); modifier_value = 0; }
|
||
;
|
||
|
||
extends_interfaces:
|
||
EXTENDS_TK interface_type
|
||
| extends_interfaces C_TK interface_type
|
||
;
|
||
|
||
interface_body:
|
||
OCB_TK CCB_TK
|
||
| OCB_TK interface_member_declarations CCB_TK
|
||
;
|
||
|
||
interface_member_declarations:
|
||
interface_member_declaration
|
||
| interface_member_declarations interface_member_declaration
|
||
;
|
||
|
||
interface_member_declaration:
|
||
constant_declaration
|
||
| abstract_method_declaration
|
||
| class_declaration /* Added, JDK1.1 inner classes */
|
||
| interface_declaration /* Added, JDK1.1 inner classes */
|
||
;
|
||
|
||
constant_declaration:
|
||
field_declaration
|
||
;
|
||
|
||
abstract_method_declaration:
|
||
method_header SC_TK
|
||
;
|
||
|
||
/* 19.10 Productions from 10: Arrays */
|
||
array_initializer:
|
||
OCB_TK CCB_TK
|
||
| OCB_TK variable_initializers CCB_TK
|
||
| OCB_TK C_TK CCB_TK
|
||
| OCB_TK variable_initializers C_TK CCB_TK
|
||
;
|
||
|
||
variable_initializers:
|
||
variable_initializer
|
||
| variable_initializers C_TK variable_initializer
|
||
;
|
||
|
||
/* 19.11 Production from 14: Blocks and Statements */
|
||
block:
|
||
OCB_TK CCB_TK
|
||
| OCB_TK block_statements CCB_TK
|
||
;
|
||
|
||
block_statements:
|
||
block_statement
|
||
| block_statements block_statement
|
||
;
|
||
|
||
block_statement:
|
||
local_variable_declaration_statement
|
||
| statement
|
||
| class_declaration /* Added, JDK1.1 inner classes */
|
||
;
|
||
|
||
local_variable_declaration_statement:
|
||
local_variable_declaration SC_TK /* Can't catch missing ';' here */
|
||
;
|
||
|
||
local_variable_declaration:
|
||
type variable_declarators
|
||
{ USE_ABSORBER; }
|
||
| modifiers type variable_declarators /* Added, JDK1.1 final locals */
|
||
{ modifier_value = 0; }
|
||
;
|
||
|
||
statement:
|
||
statement_without_trailing_substatement
|
||
| labeled_statement
|
||
| if_then_statement
|
||
| if_then_else_statement
|
||
| while_statement
|
||
| for_statement
|
||
;
|
||
|
||
statement_nsi:
|
||
statement_without_trailing_substatement
|
||
| labeled_statement_nsi
|
||
| if_then_else_statement_nsi
|
||
| while_statement_nsi
|
||
| for_statement_nsi
|
||
;
|
||
|
||
statement_without_trailing_substatement:
|
||
block
|
||
| empty_statement
|
||
| expression_statement
|
||
| switch_statement
|
||
| do_statement
|
||
| break_statement
|
||
| continue_statement
|
||
| return_statement
|
||
| synchronized_statement
|
||
| throw_statement
|
||
| try_statement
|
||
;
|
||
|
||
empty_statement:
|
||
SC_TK
|
||
;
|
||
|
||
label_decl:
|
||
identifier REL_CL_TK
|
||
{ USE_ABSORBER; }
|
||
;
|
||
|
||
labeled_statement:
|
||
label_decl statement
|
||
;
|
||
|
||
labeled_statement_nsi:
|
||
label_decl statement_nsi
|
||
;
|
||
|
||
/* We concentrate here a bunch of error handling rules that we couldn't write
|
||
earlier, because expression_statement catches a missing ';'. */
|
||
expression_statement:
|
||
statement_expression SC_TK
|
||
;
|
||
|
||
statement_expression:
|
||
assignment
|
||
| pre_increment_expression
|
||
| pre_decrement_expression
|
||
| post_increment_expression
|
||
| post_decrement_expression
|
||
| method_invocation
|
||
| class_instance_creation_expression
|
||
;
|
||
|
||
if_then_statement:
|
||
IF_TK OP_TK expression CP_TK statement
|
||
;
|
||
|
||
if_then_else_statement:
|
||
IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
|
||
;
|
||
|
||
if_then_else_statement_nsi:
|
||
IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
|
||
;
|
||
|
||
switch_statement:
|
||
SWITCH_TK OP_TK expression CP_TK switch_block
|
||
;
|
||
|
||
switch_block:
|
||
OCB_TK CCB_TK
|
||
| OCB_TK switch_labels CCB_TK
|
||
| OCB_TK switch_block_statement_groups CCB_TK
|
||
| OCB_TK switch_block_statement_groups switch_labels CCB_TK
|
||
;
|
||
|
||
switch_block_statement_groups:
|
||
switch_block_statement_group
|
||
| switch_block_statement_groups switch_block_statement_group
|
||
;
|
||
|
||
switch_block_statement_group:
|
||
switch_labels block_statements
|
||
;
|
||
|
||
|
||
switch_labels:
|
||
switch_label
|
||
| switch_labels switch_label
|
||
;
|
||
|
||
switch_label:
|
||
CASE_TK constant_expression REL_CL_TK
|
||
| DEFAULT_TK REL_CL_TK
|
||
;
|
||
|
||
while_expression:
|
||
WHILE_TK OP_TK expression CP_TK
|
||
;
|
||
|
||
while_statement:
|
||
while_expression statement
|
||
;
|
||
|
||
while_statement_nsi:
|
||
while_expression statement_nsi
|
||
;
|
||
|
||
do_statement_begin:
|
||
DO_TK
|
||
;
|
||
|
||
do_statement:
|
||
do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
|
||
;
|
||
|
||
for_statement:
|
||
for_begin SC_TK expression SC_TK for_update CP_TK statement
|
||
| for_begin SC_TK SC_TK for_update CP_TK statement
|
||
;
|
||
|
||
for_statement_nsi:
|
||
for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
|
||
| for_begin SC_TK SC_TK for_update CP_TK statement_nsi
|
||
;
|
||
|
||
for_header:
|
||
FOR_TK OP_TK
|
||
;
|
||
|
||
for_begin:
|
||
for_header for_init
|
||
;
|
||
for_init: /* Can be empty */
|
||
| statement_expression_list
|
||
| local_variable_declaration
|
||
;
|
||
|
||
for_update: /* Can be empty */
|
||
| statement_expression_list
|
||
;
|
||
|
||
statement_expression_list:
|
||
statement_expression
|
||
| statement_expression_list C_TK statement_expression
|
||
;
|
||
|
||
break_statement:
|
||
BREAK_TK SC_TK
|
||
| BREAK_TK identifier SC_TK
|
||
;
|
||
|
||
continue_statement:
|
||
CONTINUE_TK SC_TK
|
||
| CONTINUE_TK identifier SC_TK
|
||
;
|
||
|
||
return_statement:
|
||
RETURN_TK SC_TK
|
||
| RETURN_TK expression SC_TK
|
||
;
|
||
|
||
throw_statement:
|
||
THROW_TK expression SC_TK
|
||
;
|
||
|
||
synchronized_statement:
|
||
synchronized OP_TK expression CP_TK block
|
||
| synchronized OP_TK expression CP_TK error
|
||
;
|
||
|
||
synchronized: /* Test lval.sub_token here */
|
||
MODIFIER_TK
|
||
{ USE_ABSORBER; }
|
||
;
|
||
|
||
try_statement:
|
||
TRY_TK block catches
|
||
| TRY_TK block finally
|
||
| TRY_TK block catches finally
|
||
;
|
||
|
||
catches:
|
||
catch_clause
|
||
| catches catch_clause
|
||
;
|
||
|
||
catch_clause:
|
||
CATCH_TK OP_TK formal_parameter CP_TK block
|
||
;
|
||
|
||
finally:
|
||
FINALLY_TK block
|
||
;
|
||
|
||
/* 19.12 Production from 15: Expressions */
|
||
primary:
|
||
primary_no_new_array
|
||
| array_creation_expression
|
||
;
|
||
|
||
primary_no_new_array:
|
||
literal
|
||
| THIS_TK
|
||
| OP_TK expression CP_TK
|
||
| class_instance_creation_expression
|
||
| field_access
|
||
| method_invocation
|
||
| array_access
|
||
/* type DOT_TK CLASS_TK doens't work. So we split the rule
|
||
'type' into its components. Missing is something for array,
|
||
which will complete the reference_type part. FIXME */
|
||
| name DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
|
||
{ USE_ABSORBER; }
|
||
| primitive_type DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
|
||
{ USE_ABSORBER; }
|
||
| VOID_TK DOT_TK CLASS_TK /* Added, JDK1.1 class literals */
|
||
/* Added, JDK1.1 inner classes. Documentation is wrong
|
||
refering to a 'ClassName' (class_name) rule that doesn't
|
||
exist. Used name instead. */
|
||
| name DOT_TK THIS_TK
|
||
{ USE_ABSORBER; }
|
||
;
|
||
|
||
class_instance_creation_expression:
|
||
NEW_TK class_type OP_TK argument_list CP_TK
|
||
| NEW_TK class_type OP_TK CP_TK
|
||
/* Added, JDK1.1 inner classes but modified to use
|
||
'class_type' instead of 'TypeName' (type_name) mentionned
|
||
in the documentation but doesn't exist. */
|
||
| NEW_TK class_type OP_TK argument_list CP_TK class_body
|
||
| NEW_TK class_type OP_TK CP_TK class_body
|
||
/* Added, JDK1.1 inner classes, modified to use name or
|
||
primary instead of primary solely which couldn't work in
|
||
all situations. */
|
||
| something_dot_new identifier OP_TK CP_TK
|
||
| something_dot_new identifier OP_TK CP_TK class_body
|
||
| something_dot_new identifier OP_TK argument_list CP_TK
|
||
| something_dot_new identifier OP_TK argument_list CP_TK class_body
|
||
;
|
||
|
||
something_dot_new: /* Added, not part of the specs. */
|
||
name DOT_TK NEW_TK
|
||
{ USE_ABSORBER; }
|
||
| primary DOT_TK NEW_TK
|
||
;
|
||
|
||
argument_list:
|
||
expression
|
||
| argument_list C_TK expression
|
||
| argument_list C_TK error
|
||
;
|
||
|
||
array_creation_expression:
|
||
NEW_TK primitive_type dim_exprs
|
||
| NEW_TK class_or_interface_type dim_exprs
|
||
| NEW_TK primitive_type dim_exprs dims
|
||
| NEW_TK class_or_interface_type dim_exprs dims
|
||
/* Added, JDK1.1 anonymous array. Initial documentation rule
|
||
modified */
|
||
| NEW_TK class_or_interface_type dims array_initializer
|
||
| NEW_TK primitive_type dims array_initializer
|
||
;
|
||
|
||
dim_exprs:
|
||
dim_expr
|
||
| dim_exprs dim_expr
|
||
;
|
||
|
||
dim_expr:
|
||
OSB_TK expression CSB_TK
|
||
;
|
||
|
||
dims:
|
||
OSB_TK CSB_TK
|
||
| dims OSB_TK CSB_TK
|
||
;
|
||
|
||
field_access:
|
||
primary DOT_TK identifier
|
||
| SUPER_TK DOT_TK identifier
|
||
;
|
||
|
||
method_invocation:
|
||
name OP_TK CP_TK
|
||
{ USE_ABSORBER; }
|
||
| name OP_TK argument_list CP_TK
|
||
{ USE_ABSORBER; }
|
||
| primary DOT_TK identifier OP_TK CP_TK
|
||
| primary DOT_TK identifier OP_TK argument_list CP_TK
|
||
| SUPER_TK DOT_TK identifier OP_TK CP_TK
|
||
| SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
|
||
;
|
||
|
||
array_access:
|
||
name OSB_TK expression CSB_TK
|
||
{ USE_ABSORBER; }
|
||
| primary_no_new_array OSB_TK expression CSB_TK
|
||
;
|
||
|
||
postfix_expression:
|
||
primary
|
||
| name
|
||
{ USE_ABSORBER; }
|
||
| post_increment_expression
|
||
| post_decrement_expression
|
||
;
|
||
|
||
post_increment_expression:
|
||
postfix_expression INCR_TK
|
||
;
|
||
|
||
post_decrement_expression:
|
||
postfix_expression DECR_TK
|
||
;
|
||
|
||
unary_expression:
|
||
pre_increment_expression
|
||
| pre_decrement_expression
|
||
| PLUS_TK unary_expression
|
||
| MINUS_TK unary_expression
|
||
| unary_expression_not_plus_minus
|
||
;
|
||
|
||
pre_increment_expression:
|
||
INCR_TK unary_expression
|
||
;
|
||
|
||
pre_decrement_expression:
|
||
DECR_TK unary_expression
|
||
;
|
||
|
||
unary_expression_not_plus_minus:
|
||
postfix_expression
|
||
| NOT_TK unary_expression
|
||
| NEG_TK unary_expression
|
||
| cast_expression
|
||
;
|
||
|
||
cast_expression: /* Error handling here is potentially weak */
|
||
OP_TK primitive_type dims CP_TK unary_expression
|
||
| OP_TK primitive_type CP_TK unary_expression
|
||
| OP_TK expression CP_TK unary_expression_not_plus_minus
|
||
| OP_TK name dims CP_TK unary_expression_not_plus_minus
|
||
;
|
||
|
||
multiplicative_expression:
|
||
unary_expression
|
||
| multiplicative_expression MULT_TK unary_expression
|
||
| multiplicative_expression DIV_TK unary_expression
|
||
| multiplicative_expression REM_TK unary_expression
|
||
;
|
||
|
||
additive_expression:
|
||
multiplicative_expression
|
||
| additive_expression PLUS_TK multiplicative_expression
|
||
| additive_expression MINUS_TK multiplicative_expression
|
||
;
|
||
|
||
shift_expression:
|
||
additive_expression
|
||
| shift_expression LS_TK additive_expression
|
||
| shift_expression SRS_TK additive_expression
|
||
| shift_expression ZRS_TK additive_expression
|
||
;
|
||
|
||
relational_expression:
|
||
shift_expression
|
||
| relational_expression LT_TK shift_expression
|
||
| relational_expression GT_TK shift_expression
|
||
| relational_expression LTE_TK shift_expression
|
||
| relational_expression GTE_TK shift_expression
|
||
| relational_expression INSTANCEOF_TK reference_type
|
||
;
|
||
|
||
equality_expression:
|
||
relational_expression
|
||
| equality_expression EQ_TK relational_expression
|
||
| equality_expression NEQ_TK relational_expression
|
||
;
|
||
|
||
and_expression:
|
||
equality_expression
|
||
| and_expression AND_TK equality_expression
|
||
;
|
||
|
||
exclusive_or_expression:
|
||
and_expression
|
||
| exclusive_or_expression XOR_TK and_expression
|
||
;
|
||
|
||
inclusive_or_expression:
|
||
exclusive_or_expression
|
||
| inclusive_or_expression OR_TK exclusive_or_expression
|
||
;
|
||
|
||
conditional_and_expression:
|
||
inclusive_or_expression
|
||
| conditional_and_expression BOOL_AND_TK inclusive_or_expression
|
||
;
|
||
|
||
conditional_or_expression:
|
||
conditional_and_expression
|
||
| conditional_or_expression BOOL_OR_TK conditional_and_expression
|
||
;
|
||
|
||
conditional_expression: /* Error handling here is weak */
|
||
conditional_or_expression
|
||
| conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
|
||
;
|
||
|
||
assignment_expression:
|
||
conditional_expression
|
||
| assignment
|
||
;
|
||
|
||
assignment:
|
||
left_hand_side assignment_operator assignment_expression
|
||
;
|
||
|
||
left_hand_side:
|
||
name
|
||
{ USE_ABSORBER; }
|
||
| field_access
|
||
| array_access
|
||
;
|
||
|
||
assignment_operator:
|
||
ASSIGN_ANY_TK
|
||
| ASSIGN_TK
|
||
;
|
||
|
||
expression:
|
||
assignment_expression
|
||
;
|
||
|
||
constant_expression:
|
||
expression
|
||
;
|
||
|
||
%%
|
||
|
||
#include "lex.c"
|
||
|
||
/* Create a new parser context */
|
||
|
||
void
|
||
java_push_parser_context ()
|
||
{
|
||
struct parser_ctxt *new =
|
||
(struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
|
||
|
||
bzero ((PTR) new, sizeof (struct parser_ctxt));
|
||
new->next = ctxp;
|
||
ctxp = new;
|
||
}
|
||
|
||
/* Actions defined here */
|
||
|
||
static void
|
||
report_class_declaration (name)
|
||
char * name;
|
||
{
|
||
extern int flag_dump_class, flag_list_filename;
|
||
|
||
if (flag_dump_class)
|
||
{
|
||
if (!previous_output)
|
||
{
|
||
if (flag_list_filename)
|
||
fprintf (out, "%s: ", input_filename);
|
||
previous_output = 1;
|
||
}
|
||
|
||
if (package_name)
|
||
fprintf (out, "%s.%s ", package_name, name);
|
||
else
|
||
fprintf (out, "%s ", name);
|
||
}
|
||
|
||
current_class = name;
|
||
}
|
||
|
||
static void
|
||
report_main_declaration (declarator)
|
||
struct method_declarator *declarator;
|
||
{
|
||
extern int flag_find_main;
|
||
|
||
if (flag_find_main
|
||
&& modifier_value == 2
|
||
&& !strcmp (declarator->method_name, "main")
|
||
&& declarator->args
|
||
&& declarator->args [0] == '['
|
||
&& (! strcmp (declarator->args+1, "String")
|
||
|| ! strcmp (declarator->args + 1, "java.lang.String"))
|
||
&& current_class)
|
||
{
|
||
if (!previous_output)
|
||
{
|
||
if (package_name)
|
||
fprintf (out, "%s.%s ", package_name, current_class);
|
||
else
|
||
fprintf (out, current_class);
|
||
previous_output = 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* Reset global status used by the report functions. */
|
||
|
||
void reset_report ()
|
||
{
|
||
previous_output = 0;
|
||
current_class = package_name = NULL;
|
||
}
|
||
|
||
void
|
||
yyerror (msg)
|
||
char *msg ATTRIBUTE_UNUSED;
|
||
{
|
||
}
|
||
|
||
char *
|
||
xstrdup (s)
|
||
const char *s;
|
||
{
|
||
char *ret;
|
||
|
||
ret = xmalloc (strlen (s) + 1);
|
||
strcpy (ret, s);
|
||
return ret;
|
||
}
|