# BNF grammar for Java
#
# Copyright (C) 2000, 2001 Paul F. Kinnucan, Jr.
# Copyright (C) 2001 David Ponce
#
# Author: Paul F. Kinnucan, Jr. <paulk@mathworks.com>
#         David Ponce <david@dponce.com>
#
# $Id: java.bnf,v 1.15 2002/05/15 19:21:02 ponced Exp $
#
# java.bnf 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 software 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 Emacs; see the file COPYING.  If not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

# --------
# Settings
# --------
%outputfile    semantic-java.el
%parsetable    semantic-toplevel-java-bovine-table
%keywordtable  semantic-java-keyword-table
%languagemode  java-mode
%setupfunction semantic-default-java-setup

%(progn
   (setq
    ;; Java numbers
    semantic-number-expression semantic-java-number-regexp
    ;; Java is case sensitive
    semantic-case-fold nil
    ;; special handling of multiple variable declarations/statement
    semantic-expand-nonterminal 'semantic-expand-java-nonterminal
    ;; function to use when creating items in imenu
    semantic-imenu-summary-function 'semantic-prototype-nonterminal
    ;; function to use for creating the imenu
    imenu-create-index-function 'semantic-create-imenu-index
    ;; Character used to separation a parent/child relationship
    semantic-type-relation-separator-character '(".")
    semantic-command-separation-character ";"
    document-comment-start "/**"
    document-comment-line-prefix " *"
    document-comment-end " */"
    ;; speedbar and imenu buckets name
    semantic-symbol->name-assoc-list-for-type-parts
    ;; In type parts
    '((type     . "Classes")
      (variable . "Variables")
      (function . "Methods"))
    semantic-symbol->name-assoc-list
    ;; Everywhere
    (append semantic-symbol->name-assoc-list-for-type-parts
            '((include  . "Imports")
              (package  . "Package")))
    ;; Semantic navigation inside 'type children
    senator-step-at-token-ids '(function variable)
    )
   )%

%token ABSTRACT     "abstract"
%put ABSTRACT summary
"Class|Method declaration modifier: abstract {class|<type>} <name> ..."

%token BOOLEAN      "boolean"
%put BOOLEAN summary
"Primitive logical quantity type (true or false)"

%token BREAK        "break"
%put BREAK summary
"break [<label>] ;"

%token BYTE         "byte"
%put BYTE summary
"Integral primitive type (-128 to 127)"

%token CASE         "case"
%put CASE summary
"switch(<expr>) {case <const-expr>: <stmts> ... }"

%token CATCH        "catch"
%put CATCH summary
"try {<stmts>} catch(<parm>) {<stmts>} ... "

%token CHAR         "char"
%put CHAR summary
"Integral primitive type ('\u0000' to '\uffff') (0 to 65535)"

%token CLASS        "class"
%put CLASS summary
"Class declaration: class <name>"

%token CONST        "const"
%put CONST summary
"Unused reserved word"

%token CONTINUE     "continue"
%put CONTINUE summary
"continue [<label>] ;"

%token DEFAULT      "default"
%put DEFAULT summary
"switch(<expr>) { ... default: <stmts>}"

%token DO           "do"
%put DO summary
"do <stmt> while (<expr>);"

%token DOUBLE       "double"
%put DOUBLE summary
"Primitive floating-point type (double-precision 64-bit IEEE 754)"

%token ELSE         "else"
%put ELSE summary
"if (<expr>) <stmt> else <stmt>"

%token EXTENDS      "extends"
%put EXTENDS summary
"SuperClass|SuperInterfaces declaration: extends <name> [, ...]"

%token FINAL        "final"
%put FINAL summary
"Class|Member declaration modifier: final {class|<type>} <name> ..."

%token FINALLY      "finally"
%put FINALLY summary
"try {<stmts>} ... finally {<stmts>}"

%token FLOAT        "float"
%put FLOAT summary
"Primitive floating-point type (single-precision 32-bit IEEE 754)"

%token FOR          "for"
%put FOR summary
"for ([<init-expr>]; [<expr>]; [<update-expr>]) <stmt>"

%token GOTO         "goto"
%put GOTO summary
"Unused reserved word"

%token IF           "if"
%put IF summary
"if (<expr>) <stmt> [else <stmt>]"

%token IMPLEMENTS   "implements"
%put IMPLEMENTS summary
"Class SuperInterfaces declaration: implements <name> [, ...]"

%token IMPORT       "import"
%put IMPORT summary
"Import package declarations: import <package>"

%token INSTANCEOF   "instanceof"

%token INT          "int"
%put INT summary
"Integral primitive type (-2147483648 to 2147483647)"

%token INTERFACE    "interface"
%put INTERFACE summary
"Interface declaration: interface <name>"

%token LONG         "long"
%put LONG summary
"Integral primitive type (-9223372036854775808 to 9223372036854775807)"

%token NATIVE       "native"
%put NATIVE summary
"Method declaration modifier: native <type> <name> ..."

%token NEW          "new"

%token PACKAGE      "package"
%put PACKAGE summary
"Package declaration: package <name>"

%token PRIVATE      "private"
%put PRIVATE summary
"Access level modifier: private {class|interface|<type>} <name> ..."

%token PROTECTED    "protected"
%put PROTECTED summary
"Access level modifier: protected {class|interface|<type>} <name> ..."

%token PUBLIC       "public"
%put PUBLIC summary
"Access level modifier: public {class|interface|<type>} <name> ..."

%token RETURN       "return"
%put RETURN summary
"return [<expr>] ;"

%token SHORT        "short"
%put SHORT summary
"Integral primitive type (-32768 to 32767)"

%token STATIC       "static"
%put STATIC summary
"Declaration modifier: static {class|interface|<type>} <name> ..."

%token STRICTFP     "strictfp"
%put STRICTFP summary
"Declaration modifier: strictfp {class|interface|<type>} <name> ..."

%token SUPER        "super"

%token SWITCH       "switch"
%put SWITCH summary
"switch(<expr>) {[case <const-expr>: <stmts> ...] [default: <stmts>]}"


%token SYNCHRONIZED "synchronized"
%put SYNCHRONIZED summary
"synchronized (<expr>) ... | Method decl. modifier: synchronized <type> <name> ..."

%token THIS         "this"

%token THROW        "throw"
%put THROW summary
"throw <expr> ;"

%token THROWS       "throws"
%put THROWS summary
"Method|Constructor declaration: throws <classType>, ..."

%token TRANSIENT    "transient"
%put TRANSIENT summary
"Field declaration modifier: transient <type> <name> ..."

%token TRY          "try"
%put TRY summary
"try {<stmts>} [catch(<parm>) {<stmts>} ...] [finally {<stmts>}]"

%token VOID         "void"
%put VOID summary
"Method return type: void <name> ..."

%token VOLATILE     "volatile"
%put VOLATILE summary
"Field declaration modifier: volatile <type> <name> ..."

%token WHILE        "while"
%put WHILE summary
"while (<expr>) <stmt> | do <stmt> while (<expr>);"
  
# --------------------------
# Official javadoc line tags
# --------------------------

# Javadoc tags are identified by a 'javadoc' keyword property.  The
# value of this property must be itself a property list where the
# following properties are recognized:
#
# - `seq' (mandatory) is the tag sequence number used to check if tags
#   are correctly ordered in a javadoc comment block.
#
# - `usage' (mandatory) is the list of token categories for which this
#   documentation tag is allowed.
#
# - `opt' (optional) if non-nil indicates this is an optional tag.
#   By default tags are mandatory.
#
# - `with-name' (optional) if non-nil indicates that this tag is
#   followed by an identifier like in "@param <var-name> description"
#   or "@exception <class-name> description".
#
# - `with-ref' (optional) if non-nil indicates that the tag is
#   followed by a reference like in "@see <reference>".

%token _AUTHOR      "@author"
%put   _AUTHOR      javadoc (seq 1 usage (type))
%token _VERSION     "@version"
%put   _VERSION     javadoc (seq 2 usage (type)) 
%token _PARAM       "@param"
%put   _PARAM       javadoc (seq 3 usage (function) with-name t) 
%token _RETURN      "@return"
%put   _RETURN      javadoc (seq 4 usage (function)) 
%token _EXCEPTION   "@exception"
%put   _EXCEPTION   javadoc (seq 5 usage (function) with-name t) 
%token _THROWS      "@throws"
%put   _THROWS      javadoc (seq 6 usage (function) with-name t) 
%token _SEE         "@see"
%put   _SEE         javadoc (seq 7 usage (type function variable) opt t with-ref t) 
%token _SINCE       "@since"
%put   _SINCE       javadoc (seq 8 usage (type function variable) opt t) 
%token _SERIAL      "@serial"
%put   _SERIAL      javadoc (seq 9 usage (variable) opt t) 
%token _SERIALDATA  "@serialData"
%put   _SERIALDATA  javadoc (seq 10 usage (function) opt t) 
%token _SERIALFIELD "@serialField"
%put   _SERIALFIELD javadoc (seq 11 usage (variable) opt t) 
%token _DEPRECATED  "@deprecated"
%put   _DEPRECATED  javadoc (seq 12 usage (type function variable) opt t) 

# --------
# Grammar
# --------
bovine-toplevel : package_declaration
                | import_declaration
                | type_declaration
                ;
  
literal : number
        | qualified_name
        | string
        ;

type : reference_type
       (,$1)
     | primitive_type
       (,$1)
     ;
  
primitive_type : BOOLEAN | BYTE | SHORT | INT | LONG | CHAR | FLOAT | DOUBLE
               ;

reference_type : array_type
                 (,$1)
               | qualified_name
                 (,$1)
               ;
  
array_type : primitive_type dims
             ((concat (car $1) (car $2)))
           | qualified_name dims
             ((concat (car $1) (car $2)))
           ;

qualified_name : symbol punctuation "\\." qualified_name
                 ((concat $1 $2 (car $3)))
               | symbol
                 ($1)
               ;

## TOP-LEVEL ENTRY: package definition.
##  ("NAME" package DETAIL "DOCSTRING")
package_declaration : PACKAGE qualified_name punctuation ";"
                      (,$2 package nil nil)
                    ;
  

## TOP-LEVEL ENTRY: import definition.
##  ("FILE" include SYSTEM "DOCSTRING")
import_declaration : IMPORT qualified_name punctuation ";"
                     (,$2 include nil nil)
                   | IMPORT qualified_name punctuation "\\." punctuation "*" punctuation ";"
                     ((concat (car $2) $3 $4) include nil nil)
                   ;
  
type_declaration : punctuation ";"
                 | class_declaration
                 | interface_declaration
                 ;

modifiers_opt : modifiers
                (,$1)
              | EMPTY
              ;
  
modifiers : modifier modifiers
            (,(cons (car $1) ,$2))
          | modifier
            (,$1)
          ;
  
modifier : PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT
         | FINAL | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | STRICTFP
         ;

## TOP-LEVEL ENTRY: class definition.
##  ("NAME" type "TYPE" PART-LIST PARENTS EXTRA-SPECS "DOCSTRING")
class_declaration : modifiers_opt CLASS qualified_name class_parents class_body
                    ( ,$3 type "class" $5 $4
                         (ASSOC typemodifiers $1)
                          nil
                          )
                  ;

# class_parents := nil | (["extends_this" | nil] ["implements_this1" ... "implements_thisN"])
class_parents: super interfaces
               (,(append $1 $2))
             | interfaces super
               (,(append $2 $1))
             | super
               (,$1)
             | interfaces
               (,(cons nil $1))
             | EMPTY
             ;
  
super : EXTENDS qualified_name
        (,$2)
      ;
  
interfaces : IMPLEMENTS qualified_name_list
             (,$2)
           ;
  
qualified_name_list : qualified_name punctuation "," qualified_name_list
                      (,(cons (car $1) ,$3))
                    | qualified_name
                      (,$1)
                    ;
  
class_body : semantic-list # ::= {class_body_declarations}
             (EXPANDFULL $1 class_body_declarations)
           ;
  
class_body_declarations : class_declaration
                          (,$1)
                        | interface_declaration
                          (,$1)
                        | field_declaration
                          (,$1)
                        | method_declaration
                          (,$1)
                        #| static_initializer
                        | constructor_declaration
                          (,$1)
                        #| block
                        ;
  
## TOP-LEVEL ENTRY: variable definition.
##  ("NAME" variable "TYPE" DEFAULT-VALUE EXTRA-SPECS "DOCSTRING")
field_declaration : modifiers_opt type variable_declarators punctuation ";"
                    (,$3 variable ,$2 nil
                         (ASSOC typemodifiers $1)
                          nil)
                  ;

## The following rule is used by `semantic-expand-java-nonterminal' to
## reparse declaration of multiple variables in the same statement.
## Reparsing is done with `semantic-bovinate-from-nonterminal-full' to
## get correct START END information for each variable token.
field_declaration_multi : modifiers_opt type variable_declarator punctuation ","
                          (,$3)
                        | modifiers_opt type variable_declarator punctuation ";"
                          (,$3)
                        | variable_declarator punctuation ","
                          (,$1)
                        | variable_declarator punctuation ";"
                          (,$1)
                        ;
                         
variable_declarators : variable_declarator variable_declarators_opt
                       ((cons (car $1) (car $2)))
                     ;

variable_declarators_opt: punctuation "," variable_declarators
                          (,$2)
                        | EMPTY
                        ;

variable_declarator : variable_declarator_id variable_assign_opt
                      (,$1)
                    ;

variable_assign_opt: punctuation "=" variable_initializer
                   | EMPTY
                   ;

variable_declarator_id : symbol dims
                         ((concat $1 (car $2)))
                       | symbol
                         ($1)
                       ;

variable_initializer : array_initializer
                     | expression
                     ;

method_declaration : method_header method_body
                     (,$1)
                   ;
  
## TOP-LEVEL ENTRY: method definition.
##  ("NAME" function "TYPE" ARG-LIST EXTRA-SPECS "DOCSTRING")
method_header : modifiers_opt method_type symbol formal_parameter_list_opt throws_opt
                ($3 function ,$2 $4
                    (ASSOC typemodifiers $1 throws $5)
                     nil)
              ;

method_type: VOID
             ($1)
           | type
             (,$1)
           ;
  
formal_parameter_list_opt : semantic-list # ::= (formal_parameter_list)
                            (EXPANDFULL $1 formal_parameter_list)
                          | EMPTY
                          ;
  
formal_parameter_list : formal_parameter punctuation ","
                        (,$1)
                      | formal_parameter
                        (,$1)
                      ;

formal_parameter-modifier : FINAL
                          | EMPTY
                          ;

## TOP-LEVEL ENTRY: variable definition.
##  ("NAME" variable "TYPE" DEFAULT-VALUE EXTRA-SPECS "DOCSTRING")
formal_parameter : formal_parameter-modifier type variable_declarator_id
                   (,$3 variable ,$2 nil
                    (ASSOC typemodifiers $1)
                     nil)
                 ;
  
throws_opt : throws
             (,$1)
           | EMPTY
           ;
  
throws : THROWS qualified_name_list
         (,$2)
       ;
  
method_body : punctuation ";"
            | block
            ;

#static_initializer : STATIC block
#                   ;

## TOP-LEVEL ENTRY: constructor definition.
##  ("NAME" function "TYPE" ARG-LIST EXTRA-SPECS "DOCSTRING")
constructor_declaration : modifiers_opt symbol formal_parameter_list_opt throws_opt
                          constructor_body
                          ($2 function nil $3
                              (ASSOC typemodifiers $1 throws $4)
                               nil)
                        ;
  
constructor_body : block
                 ;

## TOP-LEVEL ENTRY: interface definition.
##  ("NAME" type "TYPE" PART-LIST PARENTS EXTRA-SPECS "DOCSTRING")
interface_declaration : modifiers_opt INTERFACE symbol interface_parents interface_body
                        ($3 type "interface" $5 $4
                            (ASSOC typemodifiers $1)
                             nil)
                      ;

# interface_parents := nil | ("extends_this1" ... "extends_thisN")
interface_parents : EXTENDS qualified_name_list
                    (,$2)
                  | EMPTY
                  ;
  
interface_body : semantic-list # ::= { interface_body_declarations }
                 (EXPANDFULL $1 interface_body_declarations)
               ;
  
interface_body_declarations : class_declaration
                              (,$1)
                            | interface_declaration
                              (,$1)
                            | method_header punctuation ";"
                              (,$1)
                            | field_declaration
                              (,$1)
                            ;
  
array_initializer : semantic-list "\\`{" # ::= {expression, expression, ...}
                  ;
  
block : semantic-list "\\`{" # ::= {statements}
      ;
  
primary : array_creation_expression
        | primary_no_new_array primary_dim_opt
        ;

primary_dim_opt : semantic-list "\\`\\["
                | EMPTY
                ;
  
primary_no_new_array : qualified_name semantic-list "\\`(" # method_invocation
                     | class_instance_creation_expression
                     | semantic-list "\\`(" # (expression)
                     | array_type punctuation "\\." CLASS
                     | literal
                     ;

class_instance_creation_expression : NEW qualified_name semantic-list "\\`("
                                     semantic-list "\\`{" # ::= { class_body_declarations }
                                   | NEW qualified_name semantic-list "\\`("
                                   ;
  
## array_creation_expression : NEW qualified_name dims array_initializer
##                           | NEW qualified_name dims #dim_exprs dims_opt
##                           ;
array_creation_expression : NEW array_type array_initializer
                          | NEW array_type #dim_exprs dims_opt
                          ;
  
dims_opt : dims
           (,$1)
         | EMPTY
           (nil)
         ;

dims: semantic-list "\\`\\[" dims_opt
      ((concat "[]" (car ,$2)))
    ;
  
field_access : primary punctuation "\\." symbol
             | qualified_name
             ;
  
postfix_expression : primary postfix_operator_opt
                   ;

postfix_operator_opt: punctuation "[-+]" punctuation "[-+]"
                    | EMPTY
                    ;

unary_expression : punctuation "[-+^!]" unary_expression
                 | punctuation "[-+]" punctuation "[-+]" unary_expression
                 | semantic-list "\\`(" unary_expression # cast
                 | postfix_expression
                 ;

operator: punctuation "[-+*/%=<>^~&|!?:.]" # added DOT as field/method access operator
        | INSTANCEOF 
        ;

operators: operator operators
         | operator
         ;

operators_expression_opt: operators expression
                        | EMPTY
                        ;

expression: unary_expression operators_expression_opt
          ;

# End of java.bnf