%{	/* asc.y -- written by Alexis WILKE for Made to Order Software Corp. (c) 2005-2007 */
	/* grammar parser for SSWF Action Scripts */

/*

Copyright (c) 2005-2007 Made to Order Software Corp.

Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and
associated documentation files (the "Software"), to
deal in the Software without restriction, including
without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the
following conditions:

The above copyright notice and this permission notice
shall be included in all copies or substantial
portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

*/


#include	"sswf.h"

#define	YYPARSE_PARAM		result
static	void			yyerror(const char *msg);



%}



%union
{
	struct node_t		*node;
	int			unused;
};


/* terminals */

%token	<node>		AS
%token	<node>		ASSIGNMENT		// = := *= /= %= += -= <<= >>= >>>= &= ^= |= &&= ^^= ||=
%token	<node>		BREAK
%token	<node>		CASE
%token	<node>		CATCH
%token	<node>		CLASS
%token	<node>		CONST
%token	<node>		CONTINUE
%token	<node>		DECREMENT		// --
%token	<node>		DEFAULT
%token	<node>		DELETE
%token	<node>		DO
%token	<node>		ELIPSIS			// ...
%token	<node>		ELSE
%token	<node>		EQUAL			// ==
%token	<node>		EXTENDS
%token	<node>		FALSE
%token	<node>		FOR
%token	<node>		FOR_IN			// IN when FOR was encountered
%token	<node>		FINALLY
%token	<node>		FUNCTION
%token	<node>		GOTO
%token	<node>		GREATER_EQUAL		// >=
%token	<node>		IDENTIFIER
%token	<node>		IF
%token	<node>		IMPLEMENTS
%token	<node>		IMPORT
%token	<node>		IN
%token	<node>		INCREMENT		// ++
%token	<node>		INSTANCEOF
%token	<node>		INTERFACE
%token	<node>		IS
%token	<node>		LOGICAL_AND		// &&
%token	<node>		LOGICAL_OR		// ||
%token	<node>		LOGICAL_XOR		// ^^
%token	<node>		NAMESPACE
%token	<node>		NEGATED_MIN_LONG
%token	<node>		NEW
%token	<node>		NOT_EQUAL		// != <> (?)
%token	<node>		NULL_LITERAL		// null
%token	<node>		NUMBER
%token	<node>		LESS_EQUAL		// <=
%token	<node>		PACKAGE
%token	<node>		POWER			// **
%token	<node>		PRIVATE
%token	<node>		PUBLIC
%token	<node>		REGULAR_EXPRESSION	// /<expr>/<flags>
%token	<node>		RETURN
%token	<node>		ROTATE_LEFT		// !<
%token	<node>		ROTATE_RIGHT		// !>
%token	<node>		SCOPE			// ::
%token	<node>		SHIFT_LEFT		// <<
%token	<node>		SHIFT_RIGHT		// >>
%token	<node>		SHIFT_RIGHT_UNSIGNED	// >>>
%token	<node>		STRICTLY_EQUAL		// ===
%token	<node>		STRICTLY_NOT_EQUAL	// !==
%token	<node>		STRING
%token	<node>		SUPER
%token	<node>		SWITCH
%token	<node>		THIS
%token	<node>		THROW
%token	<node>		TRUE
%token	<node>		TRY
%token	<node>		TYPEOF
%token	<node>		USE
%token	<node>		VAR
%token	<node>		VOID
%token	<node>		WITH
%token	<node>		WHILE


/* For many of the following, not listed in reserved keywords because those are just attributes:

	ABSTRACT
	DYNAMIC
	ENUMERABLE
	EXPLICIT
	FALSE
	FINAL
	INTERNAL
	INTRINSIC
	OVERRIDE [ '(' TRUE | FALSE | UNDEFINED ')' ]
	PRIVATE
	PROTECTED
	PROTOTYPE
	PUBLIC
	STATIC
	TRUE
	UNUSED
	VIRTUAL

[modifiers] enum enumName [ : typeAnnotation]{
   enumValue1 [ = initializer1]
   [,enumValue2 [ = initializer2]
   [, ... [,enumValueN [ = initializerN ] ]]]
}

*/


/* all these yacc expressions are nodes */




%%

start:
	   expression_statement //program
	   {
	   }
;





simple_qualified_identifier:
	   IDENTIFIER
	   {
	   }
	|  IDENTIFIER SCOPE IDENTIFIER
	   {
	   }
	|  reserved_namespace SCOPE IDENTIFIER
	   {
	   }
;


expression_qualified_identifier:
	   paren_expression SCOPE IDENTIFIER
	   {
	   }
;


qualified_identifier:
	   simple_qualified_identifier
	   {
	   }
	|  expression_qualified_identifier
	   {
	   }
;


primary_expression:
	   NULL_LITERAL
	   {
	   }
	|  TRUE
	   {
	   }
	|  FALSE
	   {
	   }
	|  NUMBER
	   {
	   }
	|  STRING
	   {
	   }
	|  THIS
	   {
	   }
	|  REGULAR_EXPRESSION
	   {
	   }
	|  reserved_namespace
	   {
	   }
	|  paren_list_expression
	   {
	   }
	|  array_literal
	   {
	   }
	|  object_literal
	   {
	   }
	|  function_expression
	   {
	   }
;


reserved_namespace:
	   PUBLIC
	   {
	   }
	|  PRIVATE
	   {
	   }
;


paren_expression:
	   '(' assignment_expression ')'
	   {
	   }
;



paren_list_expression:
	   paren_expression
	   {
	   }
	|  '(' list_expression ',' assignment_expression ')'
	   {
	   }
;



function_expression:
	   FUNCTION function_common
	   {
	   }
	|  FUNCTION IDENTIFIER function_common
	   {
	   }
;


object_literal:
	   '{' field_list '}'
	   {
	   }
	|  '{' '}'
	   {
	   }
;




field_list:
	   nonempty_field_list
	   {
	   }
;


nonempty_field_list:
	   literal_field
	   {
	   }
	|  literal_field ',' nonempty_field_list
	   {
	   }
;


literal_field:
	   field_name ':' assignment_expression
	   {
	   }
;


field_name:
	   qualified_identifier
	   {
	   }
	|  STRING
	   {
	   }
	|  NUMBER
	   {
	   }
	|  paren_expression
	   {
	   }
;



array_literal:
	   '[' ']'
	   {
	   }
	|  '[' comma_list ']'
	   {
	   }
	|  '[' element_list ']'
	   {
	   }
	|  '[' element_list comma_list ']'
	   {
	   }
	|  '[' comma_list element_list comma_list ']'
	   {
	   }
;


element_list:
	   literal_element
	   {
	   }
	|  element_list comma_list literal_element
	   {
	   }
;


comma_list:
	   ','
	   {
	   }
	|  comma_list ','
	   {
	   }
;


literal_element:
	   assignment_expression
	   {
	   }
;



super_expression:
	   SUPER
	   {
	   }
	|  SUPER paren_expression
	   {
	   }
;


postfix_expression:
	   attribute_expression
	   {
	   }
	|  full_postfix_expression
	   {
	   }
	|  short_new_expression
	   {
	   }
;


attribute_expression:
	   simple_qualified_identifier
	   {
	   }
	|  attribute_expression property_operator
	   {
	   }
	|  attribute_expression arguments
	   {
	   }
;


full_postfix_expression:
	   primary_expression
	   {
	   }
	|  expression_qualified_identifier
	   {
	   }
	|  full_new_expression
	   {
	   }
	|  full_postfix_expression property_operator
	   {
	   }
	|  super_expression property_operator
	   {
	   }
	|  full_postfix_expression arguments
	   {
	   }
	|  postfix_expression INCREMENT
	   {
	   }
	|  postfix_expression DECREMENT
	   {
	   }
;


full_new_expression:
	   NEW full_new_subexpression arguments
	   {
	   }
;


full_new_subexpression:
	   primary_expression
	   {
	   }
	|  qualified_identifier
	   {
	   }
	|  full_new_expression
	   {
	   }
	|  full_new_subexpression property_operator
	   {
	   }
	|  super_expression property_operator
	   {
	   }
;


short_new_expression:
	   NEW short_new_subexpression
	   {
	   }
;


short_new_subexpression:
	   full_new_subexpression
	   {
	   }
	|  short_new_expression
	   {
	   }
;




property_operator:
	   '.' qualified_identifier
	   {
	   }
	|  brackets
	   {
	   }
;


brackets:
	   '[' ']'
	   {
	   }
	|  '[' list_expression ']'
	   {
	   }
	|  '[' expressions_with_rest ']'
	   {
	   }
;


arguments:
	   '(' ')'
	   {
	   }
	|  paren_list_expression
	   {
	   }
	|  '(' expressions_with_rest ')'
	   {
	   }
;


expressions_with_rest:
	   rest_expression
	   {
	   }
	|  list_expression ',' rest_expression
	   {
	   }
;


rest_expression:
	   ELIPSIS assignment_expression
	   {
	   }
;



unary_expression:
	   postfix_expression
	   {
	   }
	|  DELETE postfix_expression
	   {
	   }
	|  VOID unary_expression
	   {
	   }
	|  TYPEOF unary_expression
	   {
	   }
	|  INCREMENT postfix_expression
	   {
	   }
	|  DECREMENT postfix_expression
	   {
	   }
	|  '+' unary_expression
	   {
	   }
	|  '-' unary_expression
	   {
	   }
	|  '-' NEGATED_MIN_LONG
	   {
	   }
	|  '~' unary_expression
	   {
	   }
	|  '!' unary_expression
	   {
	   }
;




power_expression:
	   unary_expression
	   {
	   }
	|  power_expression POWER unary_expression
	   {
	   }
;




multiplicative_expression:
	   power_expression
	   {
	   }
	|  multiplicative_expression '*' power_expression
	   {
	   }
	|  multiplicative_expression '/' power_expression
	   {
	   }
	|  multiplicative_expression '%' power_expression
	   {
	   }
;




additive_expression:
	   multiplicative_expression
	   {
	   }
	|  additive_expression '+' multiplicative_expression
	   {
	   }
	|  additive_expression '-' multiplicative_expression
	   {
	   }
;


shift_expression:
	   additive_expression
	   {
	   }
	|  shift_expression SHIFT_LEFT additive_expression
	   {
	   }
	|  shift_expression SHIFT_RIGHT additive_expression
	   {
	   }
	|  shift_expression SHIFT_RIGHT_UNSIGNED additive_expression
	   {
	   }
	|  shift_expression ROTATE_LEFT additive_expression
	   {
	   }
	|  shift_expression ROTATE_RIGHT additive_expression
	   {
	   }
;



relational_expression:
	   shift_expression
	   {
	   }
	|  relational_expression '<' shift_expression
	   {
	   }
	|  relational_expression '>' shift_expression
	   {
	   }
	|  relational_expression LESS_EQUAL shift_expression
	   {
	   }
	|  relational_expression GREATER_EQUAL shift_expression
	   {
	   }
	|  relational_expression IS shift_expression
	   {
	   }
	|  relational_expression AS shift_expression
	   {
	   }
	|  relational_expression IN shift_expression
	   {
	   }
	|  relational_expression INSTANCEOF shift_expression
	   {
	   }
;



equality_expression:
	   relational_expression
	   {
	   }
	|  equality_expression EQUAL relational_expression
	   {
	   }
	|  equality_expression NOT_EQUAL relational_expression
	   {
	   }
	|  equality_expression STRICTLY_EQUAL relational_expression
	   {
	   }
	|  equality_expression STRICTLY_NOT_EQUAL relational_expression
	   {
	   }
;




bitwise_and_expression:
	   equality_expression
	   {
	   }
	|  bitwise_and_expression '&' equality_expression
	   {
	   }
;


bitwise_xor_expression:
	   bitwise_and_expression
	   {
	   }
	|  bitwise_xor_expression '^' bitwise_and_expression
	   {
	   }
;


bitwise_or_expression:
	   bitwise_xor_expression
	   {
	   }
	|  bitwise_or_expression '|' bitwise_xor_expression
	   {
	   }
;




logical_and_expression:
	   bitwise_or_expression
	   {
	   }
	|  logical_and_expression LOGICAL_AND bitwise_or_expression
	   {
	   }
;



logical_xor_expression:
	   logical_and_expression
	   {
	   }
	|  logical_xor_expression LOGICAL_XOR logical_and_expression
	   {
	   }
;



logical_or_expression:
	   logical_xor_expression
	   {
	   }
	|  logical_or_expression LOGICAL_OR logical_xor_expression
	   {
	   }
;



conditional_expression:
	   logical_or_expression
	   {
	   }
	|  logical_or_expression '?' assignment_expression ':' assignment_expression
	   {
	   }
;



non_assignment_expression:
	   logical_or_expression
	   {
	   }
	|  logical_or_expression '?' non_assignment_expression ':' non_assignment_expression
	   {
	   }
;





assignment_expression:
	   conditional_expression
	   {
	   }
	|  postfix_expression ASSIGNMENT assignment_expression
	   {
	   }
;


list_expression:
	   assignment_expression
	   {
	   }
	|  list_expression ',' assignment_expression
	   {
	   }
;


type_expression:
	   non_assignment_expression
	   {
	   }
;




statement:
	   /* this expression can't start with function nor '{' */
	   expression_statement ';'
	   {
	   }
	|  super_statement ';'
	   {
	   }
	|  block
	   {
	   }
	|  labeled_statement
	   {
	   }
	|  goto_statement
	   {
	   }
	|  if_statement
	   {
	   }
	|  switch_statement
	   {
	   }
	|  do_statement ';'
	   {
	   }
	|  while_statement
	   {
	   }
	|  for_statement
	   {
	   }
	|  with_statement
	   {
	   }
	|  continue_statement ';'
	   {
	   }
	|  break_statement ';'
	   {
	   }
	|  return_statement ';'
	   {
	   }
	|  throw_statement ';'
	   {
	   }
	|  try_statement
	   {
	   }
	|  catch_statement
	   {
	   }
	|  finally_statement
	   {
	   }
;


substatement:
	   empty_statement
	   {
	   }
	|  statement
	   {
	   }
	|  simple_variable_definition ';'
	   {
	   }
	|  attributes '{' '}'
	   {
	   }
	|  attributes '{' substatement_list '}'
	   {
	   }
;


substatement_list:
	   substatement
	   {
	   }
	|  substatement_list substatement
	   {
	   }
;







empty_statement:
	   ';'
	   {
	   }
;



expression_statement:
	   list_expression
	   {
	   }
;



super_statement:
	   SUPER arguments
	   {
	   }
;


block:
	   '{' directives '}'
	   {
	   }
	|  '{' '}'
	   {
	   }
;




labeled_statement:
	   IDENTIFIER ':' substatement
	   {
	   }
;



goto_statement:
	   GOTO IDENTIFIER
	   {
	   }
;




if_statement:
	   IF paren_list_expression substatement
	   {
	   }
	|  IF paren_list_expression substatement ELSE substatement
	   {
	   }
;








switch_statement:
	   SWITCH paren_list_expression '{' case_elements '}'
	   {
	   }
;



case_elements:
	   /* EMPTY */
	   {
	   }
	|  case_label
	   {
	   }
	|  case_label case_elements_prefix case_element
	   {
	   }
;


case_elements_prefix:
	   /* EMPTY */
	   {
	   }
	|  case_elements_prefix case_element
	   {
	   }
;


case_element:
	   directive
	   {
	   }
	|  case_label
	   {
	   }
;


case_label:
	   CASE list_expression ':'
	   {
	   }
	|  DEFAULT ':'
	   {
	   }
;



do_statement:
	   DO substatement WHILE paren_list_expression
	   {
	   }
;



while_statement:
	   WHILE paren_list_expression substatement
	   {
	   }
;




for_statement:
	   FOR '(' for_initializer ';' optional_expression ';' optional_expression ')' substatement
	   {
	   }
	|  FOR '(' for_in_binding FOR_IN list_expression ')' substatement
	   {
	   }
;


for_initializer:
	   /* EMPTY */
	   {
	   }
	|  list_expression
	   {
	   }
	|  variable_definition
	   {
	   }
	|  attributes variable_definition
	   {
	   }
;


for_in_binding:
	   postfix_expression
	   {
	   }
	|  variable_definition_kind variable_binding
	   {
	   }
	|  attributes variable_definition_kind variable_binding
	   {
	   }
;


optional_expression:
	   list_expression
	   {
	   }
	|  /* EMPTY */
	   {
	   }
;



with_statement:
	   WITH paren_list_expression substatement
	   {
	   }
;



continue_statement:
	   CONTINUE
	   {
	   }
	|  CONTINUE IDENTIFIER
	   {
	   }
;



break_statement:
	   BREAK
	   {
	   }
	|  BREAK IDENTIFIER
	   {
	   }
;




return_statement:
	   RETURN
	   {
	   }
	|  RETURN list_expression
	   {
	   }
;




throw_statement:
	   THROW list_expression
	   {
	   }
;



try_statement:
	   TRY block
	   {
	   }
;



catch_statement:
	   CATCH '(' parameter ')' block
	   {
	   }
;



finally_statement:
	   FINALLY block
	   {
	   }
;



directive:
	   empty_statement
	   {
	   }
	|  statement
	   {
	   }
	|  annotatable_directive
	   {
	   }
	|  attributes annotatable_directive
	   {
	   }
	|  attributes block
	   {
	   }
	|  pragma ';'
	   {
	   }
;



annotatable_directive:
	   variable_definition ';'
	   {
	   }
	|  function_definition
	   {
	   }
	|  class_definition
	   {
	   }
	|  interface_definition
	   {
	   }
	|  namespace_definition ';'
	   {
	   }
	|  import_directive ';'
	   {
	   }
	|  use_directive ';'
	   {
	   }
;



directives:
	   directive
	   {
	   }
	|  directives directive
	   {
	   }
;




attributes:
	   attribute
	   {
	   }
	|  attribute_combination
	   {
	   }
;




attribute_combination:
	   attribute attributes
	   {
	   }
;



attribute:
	   attribute_expression
	   {
	   }
	|  TRUE
	   {
	   }
	|  FALSE
	   {
	   }
	|  reserved_namespace
	   {
	   }
;



use_directive:
	   USE NAMESPACE paren_list_expression
	   {
	   }
;



import_directive:
	   IMPORT package_name
	   {
	   }
	|  IMPORT IDENTIFIER '=' package_name
	   {
	   }
;




pragma:
	   USE pragma_items
	   {
	   }
;


pragma_items:
	   pragma_item
	   {
	   }
	|  pragma_items ',' pragma_item
	   {
	   }
;


pragma_item:
	   pragma_expr
	   {
	   }
	|  pragma_expr '?'
	   {
	   }
;


pragma_expr:
	   IDENTIFIER
	   {
	   }
	|  IDENTIFIER '(' pragma_argument ')'
	   {
	   }
;


pragma_argument:
	   TRUE
	   {
	   }
	|  FALSE
	   {
	   }
	|  NUMBER
	   {
	   }
	|  '-' NUMBER
	   {
	   }
	|  '-' NEGATED_MIN_LONG
	   {
	   }
	|  STRING
	   {
	   }
;





variable_definition:
	   variable_definition_kind variable_binding_list
	   {
	   }
;


variable_definition_kind:
	   VAR
	   {
	   }
	|  CONST
	   {
	   }
;


variable_binding_list:
	   variable_binding
	   {
	   }
	|  variable_binding_list ',' variable_binding
	   {
	   }
;


variable_binding:
	   typed_identifier
	   {
	   }
	|  typed_identifier variable_initialisation
	   {
	   }
;


variable_initialisation:
	   '=' variable_initializer
	   {
	   }
;


variable_initializer:
	   assignment_expression
	   {
	   }
	|  attribute_combination
	   {
	   }
;


typed_identifier:
	   IDENTIFIER
	   {
	   }
	|  IDENTIFIER ':' type_expression
	   {
	   }
;



simple_variable_definition:
	   VAR untyped_variable_binding_list
	   {
	   }
;


untyped_variable_binding_list:
	   untyped_variable_binding
	   {
	   }
	|  untyped_variable_binding_list ',' untyped_variable_binding
	   {
	   }
;



untyped_variable_binding:
	   IDENTIFIER
	   {
	   }
	|  IDENTIFIER variable_initialisation
	   {
	   }
;




function_definition:
	   FUNCTION function_name function_common
	   {
	   }
;



function_name:
	   IDENTIFIER
	   {
	   }
	|  IDENTIFIER IDENTIFIER	// 1st identifier needs to be GET or SET
	   {
	   }
	|  STRING			// for operators override
	   {
	   }
;


function_common:
	   '(' parameters ')' block
	   {
	   }
	|  '(' parameters ')' result block
	   {
	   }
;



parameters:
	   /* EMPTY */
	   {
	   }
	|  nonempty_parameters
	   {
	   }
;


nonempty_parameters:
	   parameter_init
	   {
	   }
	|  parameter_init ',' nonempty_parameters
	   {
	   }
	|  rest_parameter
	   {
	   }
;


parameter:
	   parameter_attributes typed_identifier
	   {
	   }
;


parameter_attributes:
	   /* EMPTY */
	   {
	   }
	|  CONST
	   {
	   }
;


parameter_init:
	   parameter
	   {
	   }
	|  parameter '=' assignment_expression
	   {
	   }
;


rest_parameter:
	   ELIPSIS
	   {
	   }
	|  ELIPSIS parameter_attributes IDENTIFIER
	   {
	   }
;


result:
	   ':' type_expression
	   {
	   }
;




interface_definition:
	   INTERFACE IDENTIFIER extends_list block
	   {
	   }
	|  INTERFACE IDENTIFIER ';'
	   {
	   }
;


extends_list:
	   /* EMPTY */
	   {
	   }
	|  EXTENDS type_expression_list
	   {
	   }
;

type_expression_list:
	   type_expression
	   {
	   }
	|  type_expression_list ',' type_expression
	   {
	   }
;



class_definition:
	   CLASS IDENTIFIER inheritance block
	   {
	   }
;



inheritance:
	   /* EMPTY */
	   {
	   }
	|  EXTENDS type_expression
	   {
	   }
	|  IMPLEMENTS type_expression_list
	   {
	   }
	|  EXTENDS type_expression IMPLEMENTS type_expression_list
	   {
	   }
;


namespace_definition:
	   NAMESPACE IDENTIFIER
	   {
	   }
;




program:
	   directives
	   {
	   }
	|  package_definition program
	   {
	   }
;


package_definition:
	   PACKAGE package_name_opt block
	   {
	   }
;


package_name_opt:
	   /* EMPTY */
	   {
	   }
	|  package_name
	   {
	   }
;


package_name:
	   STRING
	   {
	   }
	|  package_identifiers
	   {
	   }
;


package_identifiers:
	   IDENTIFIER
	   {
	   }
	|  package_identifiers '.' IDENTIFIER
	   {
	   }
;



%%


void yyerror(const char *msg)
{
	printf("YACC ERROR at line #%d in file \"%s\": %s.\n", yylloc.first_line, lex_filename, msg);
}




