


%skeleton "lalr1.cc"
%define "parser_class_name" "VhdlBisonParser"


%defines
%{
#define yylex(yylval, location) lex.NextToken( (yylval) , (location) )
#include <string>
#include <iostream>


#include "vhdl_parser_struct.h"
#define YYSTYPE vhdl_types

#include "vhdl_parser.h"
#include "vhdl_err.h"

using namespace std;
%}

%parse-param { LexanVhdl& lex }
%parse-param { VhdlParser& driver }
%debug
%error-verbose
%expect 1
%name-prefix="vhdl_"
%output="vhdl_bison_parser.cpp"
%locations
%initial-action{
  @$.begin.filename = @$.end.filename = &driver.fn;
};

%token 
LEX_V_NULL  
LEX_V_ERROR  
LEX_V_ABS  
LEX_V_ACCESS  
LEX_V_AFTER  
LEX_V_ALIAS  
LEX_V_ALL  
LEX_V_AND  
LEX_V_ARCHITECTURE  
LEX_V_ARRAY  
LEX_V_ASSERT  
LEX_V_ATTRIBUTE  
LEX_V_BEGIN  
LEX_V_BLOCK  
LEX_V_BODY  
LEX_V_BUFFER  
LEX_V_BUS  
LEX_V_CASE  
LEX_V_COMPONENT  
LEX_V_CONFIGURATION  
LEX_V_CONSTANT  
LEX_V_DISCONNECT  
LEX_V_DOWNTO  
LEX_V_ELSE  
LEX_V_ELSIF  
LEX_V_END  
LEX_V_ENTITY  
LEX_V_EXIT  
LEX_V_FILE  
LEX_V_FOR  
LEX_V_FUNCTION  
LEX_V_GENERATE  
LEX_V_GENERIC  
LEX_V_GROUP  
LEX_V_GUARDED  
LEX_V_IF  
LEX_V_IMPURE  
LEX_V_IN  
LEX_V_INERTIAL  
LEX_V_INOUT  
LEX_V_IS  
LEX_V_LABEL  
LEX_V_LIBRARY  
LEX_V_LINKAGE  
LEX_V_LITERAL  
LEX_V_LOOP  
LEX_V_MAP  
LEX_V_NAND  
LEX_V_NEW  
LEX_V_NEXT  
LEX_V_NOR   
LEX_V_NOT  
LEX_V_OF  
LEX_V_ON  
LEX_V_OPEN  
LEX_V_OR  
LEX_V_OTHERS  
LEX_V_OUT  
LEX_V_PACKAGE  
LEX_V_PORT  
LEX_V_POSTOPENED  
LEX_V_PROCEDURE  
LEX_V_PROCESS  
LEX_V_PROTECTED  
LEX_V_PURE  
LEX_V_RANGE  
LEX_V_RECORD  
LEX_V_REGISTER  
LEX_V_REJECT  
LEX_V_REM  
LEX_V_REPORT  
LEX_V_RETURN  
LEX_V_ROL  
LEX_V_ROR  
LEX_V_SELECT  
LEX_V_SEVERENITY  
LEX_V_SHARED  
LEX_V_SIGNAL  
LEX_V_SLA  
LEX_V_SLL  
LEX_V_SRA  
LEX_V_SRL  
LEX_V_SUBTYPE  
LEX_V_THEN  
LEX_V_TO  
LEX_V_TRANSPORT  
LEX_V_TYPE  
LEX_V_UNAFFECTED  
LEX_V_UNITS  
LEX_V_UNTIL  
LEX_V_USE  
LEX_V_VARIABLE  
LEX_V_WAIT  
LEX_V_WHEN  
LEX_V_WHILE  
LEX_V_WITH  
LEX_V_XNOR  
LEX_V_XOR  
LEX_V_EOF 0
LEX_V_LITCHAR 
LEX_V_LITSTRING 
LEX_V_LITBITSTR 
LEX_V_IDENT 
LEX_V_SLASH 
LEX_V_EQUAL 
LEX_V_GRT 
LEX_V_LESS 
LEX_V_AMPER 
LEX_V_QUOT 
LEX_V_SQUOT 
LEX_V_LPAR 
LEX_V_RPAR 
LEX_V_SLPAR 
LEX_V_SRPAR 
LEX_V_DOT 
LEX_V_COMMA 
LEX_V_CROSS 
LEX_V_VLINE 
LEX_V_LOEQ 
LEX_V_GOREQ 
LEX_V_NEQ 
LEX_V_RHOMB 
LEX_V_ASSIGN 
LEX_V_POWER 
LEX_V_DDOT 
LEX_V_ASR 
LEX_V_SEMICOL 


%nonassoc LEX_V_EQUAL  LEX_V_NEQ LEX_V_LESS LEX_V_LOEQ LEX_V_GRT LEX_V_GOREQ
%nonassoc LEX_V_SLL LEX_V_SRL LEX_V_SLA LEX_V_SRA LEX_V_ROL LEX_V_ROR 
%left LEX_V_PLUS LEX_V_MINUS  LEX_V_AMPER 
%left LEX_V_ASTER LEX_V_SLASH  LEX_V_MOD  LEX_V_REM 
%nonassoc LEX_V_POWER LEX_V_ABS LEX_V_NEG

%token <ival> LEX_V_LITABSTR 
%token <sval> LEX_V_IDENT 
%token <chval> LEX_V_LITCHAR

%type <stoken> 
  mark entity_name 
  opt_component_end component_simple_name 


%type <pexpr> 
expression
or_expr
xor_expr
and_expr
xnor_expr
relation 
shift_expression
simple_expression 
signed_term 
term 
factor
primary
literal
actual_part
conditional_waveforms
waveform
waveform_elements
waveform_element
value_expression



%type <identList>
    identifier_list
    
%type <type>
  subtype_indication subtype_indic_incomplete subtype_indication_1
  


%type <interfList>
  formal_parameter_list generic_list port_list interface_element interface_declaration
  interface_csv_declaration interface_file_declaration interface_list
  port_clause local_port_clause
  signal_declaration
  
%type <mode>
  opt_mode mode
  
%type <boolean>
  opt_bus
  
%type <dir>
  direction 
  
%type <objClass>
  opt_object_class object_class
  
%type <genAssocElem>
    gen_association_element
    association_element 
    discrete_range1 
    range_2
    range_constraint
    
%type <pgenAssocList>
    gen_association_list gen_association_list_rest 
    association_list association_list_rest
    opt_index_constraint
    port_map_aspect opt_port_map_aspect
    
%type <psigName>
    name name2 index_name 
    formal_part
    target
    
%type <sval> 
    opt_architecture_identifier
    


  



%%
start:
  design_file
  ;
  
opt_configuration :
    /* NOTHING */
    | LEX_V_CONFIGURATION
    ; 
    
opt_package :
    /* NOTHING */
    | LEX_V_PACKAGE
    ;
    
opt_architecture :
    /* NOTHING */
    | LEX_V_ARCHITECTURE
    ;
    
opt_shared :
    /* NOTHING */
    | LEX_V_SHARED
    ;
    
opt_rhomb :
    /* NOTHING */
    | LEX_V_RHOMB
    ;
    
opt_is :
    /* NOTHING */
    | LEX_V_IS
    ;
    
opt_postopened :
    /* NOTHING */
    | LEX_V_POSTOPENED
    ;
  
opt_guarded :
    /* NOTHING */
    | LEX_V_GUARDED
    ;
    
opt_entity :
    /* NOTHING */
    | LEX_V_ENTITY
    ;
    
opt_bus :
    /* NOTHING */ { $$ = false; }
    | LEX_V_BUS { $$ = true; }
    ;


    
opt_ident:
    /* NOTHING */
    | LEX_V_IDENT
    ;
    

    

    
opt_abstr_lit :
    /* NOTHING */
    | LEX_V_LITABSTR
    ;
    
    
physical_lit :
    opt_abstr_lit  unit_name
    ;

unit_name :
    name
    ;    
    
entity_name :
    mark
    ;
    

    
    
entity_class_entry_list :
    entity_class_entry 
    | entity_class_entry_list LEX_V_COMMA entity_class_entry 
    ;
    
name_list :
    name { delete $1; }
    | name_list LEX_V_COMMA name
    {
      delete $3;
    }
    ;
     
identifier_list :
    LEX_V_IDENT 
      { 
        pIdentifierList il = new IdentifierList();
        il->push_back(StringToken(*$1,@1));
        $$ = il;
        delete $1;
      }
    | identifier_list LEX_V_COMMA LEX_V_IDENT 
      {  
     
        ($1)->push_back(StringToken(*$3,@3));
        $$ = $1;
        delete $3;
      }
    ;
    
logical_name_list :
    logical_name 
    | logical_name_list LEX_V_COMMA logical_name 
    ;

logical_name :
    LEX_V_IDENT { delete $1; }
    ;
    

  
///////////////////////////
// DESIGN UNITS
///////////////////////////

design_file:
    {
     driver.client_->haveUnit();
    }
    design_file1
    ;

design_file1 :
    design_unit 
    | design_file1 design_unit 
    ;
    

design_unit :
    context_clause library_unit  
    ;
    
context_clause :
    /* nothing */
    | context_clause context_item 
    ;
    
library_unit :
    primary_unit
    | secondary_unit
    ;

primary_unit :
    entity_declaration
    | configuration_declaration
    {
       throw VhdlNotYetException(NotYetReason("Configuration Declaration"),VhdlFilePosition(@1));
     }
    | package_declaration
    {
       throw VhdlNotYetException(NotYetReason("Package Declaration"),VhdlFilePosition(@1));
    }
    ;

secondary_unit :
    architecture_body
    | package_body
    ;
    
context_item :
    library_clause
    | use_clause
    ;
    
library_clause :
    LEX_V_LIBRARY logical_name_list LEX_V_SEMICOL 
    ;

use_clause :
    LEX_V_USE sel_list LEX_V_SEMICOL
    ;
    
opt_formal_parameter_list :
    /* NOTHING */
    | formal_parameter_list
    ;

formal_parameter_list :
    LEX_V_LPAR  interface_list LEX_V_RPAR { $$ = $2; }
    ;

sel_list:
	skip_selected_name		
    |	sel_list LEX_V_COMMA skip_selected_name
    ;
  
///////////////////////////
// LIBRARY UNITS
///////////////////////////  
    
////////////////////////  
// Primary unit - ENITY
////////////////////////
    
entity_declaration :
    LEX_V_ENTITY  LEX_V_IDENT 
    {
      driver.client_->haveEntity(StringToken(*$2,@2));
      delete $2;
    }
    LEX_V_IS
          entity_header
          entity_declarative_part 
          opt_entity_statement_part
    LEX_V_END opt_entity_end LEX_V_SEMICOL
    {
      driver.client_->endEntity();
    }
    ;
    
entity_header :
    opt_formal_generic_clause 
    opt_formal_port_clause 
    ;

opt_formal_generic_clause :
    /* nothing */
    | generic_clause 
    {
       throw VhdlNotYetException(NotYetReason("Formal Generic Clause"),VhdlFilePosition(@1));
     }
    ;
    
opt_formal_port_clause :
    /* nothing */ 
    | port_clause
    {   
        for(InterfaceList::iterator i=$1->begin(); i != $1->end(); ++i)
          driver.client_->havePort(*i);
    }
    ;
    
generic_clause :
    LEX_V_GENERIC LEX_V_LPAR generic_list LEX_V_RPAR LEX_V_SEMICOL
    ;
    
generic_list :
    interface_list { delete $1; }
    ;
    
generic_map_aspect :
    LEX_V_GENERIC LEX_V_MAP 
      {
       throw VhdlNotYetException(NotYetReason("Generic map"),VhdlFilePosition(@1));
      }
    association_list
    ;
    

port_clause :
    LEX_V_PORT LEX_V_LPAR port_list LEX_V_RPAR LEX_V_SEMICOL { $$ = $3;}
    ;
  
port_list :
    interface_list
    ;

port_map_aspect :
    LEX_V_PORT LEX_V_MAP  association_list { $$ = $3; }
    ;

    
entity_declarative_part :
    /* NOTHING */
    | 
    entity_declarative_part  entity_declarative_item 
    {
       throw VhdlNotYetException(NotYetReason("Entity Declarative Part"),VhdlFilePosition(@1));
    }
    ;

opt_entity_statement_part :
    /* NOTHING */
    | LEX_V_BEGIN entity_statement_part 
    {
       throw VhdlNotYetException(NotYetReason("Entity Statement Part"),VhdlFilePosition(@1));
     }
    ;

entity_statement_part :
    /* NOTHING */
    | entity_statement_part entity_statement 
    ;
    
entity_statement :
    concurrent_assertion_statement
    | passive_concurrent_procedure_call
    | passive_process_statement
    ;
    
passive_concurrent_procedure_call :
    concurrent_procedure_call_statement
    ;
    
passive_process_statement :
    process_statement
    ;
    
opt_entity_end :
    opt_entity opt_entity_simple_name 
    ;

opt_entity_simple_name :
    /* NOTHING */
    | entity_simple_name
    ;
    
entity_simple_name :
    LEX_V_IDENT
    ;
     
    
entity_declarative_item :
    subprogram_declaration
    | subprogram_body
    | type_declaration
    | subtype_declaration
    | constant_declaration
    | signal_declaration {delete $1;}
    | variable_declaration
    | file_declaration
    | alias_declaration
    | attribute_declaration
    | attribute_specification
    | disconnection_specification
    | use_clause
    | group_template_declaration
    | group_declaration 
    ;
    
/////////////////////////////////////////////////
// INTERFACE  & ASSOCIATION & SENSITIVITY LISTS
/////////////////////////////////////////////////

interface_list :
    interface_element 
    | interface_list LEX_V_SEMICOL interface_element 
      {
       for(InterfaceList::iterator i=$3->begin(); i != $3->end(); ++i){
        $1->push_back(*i);
       }
       $$ = $1;
       delete $3;
      }
    ;
    
interface_element :
    interface_declaration
    ;
    
interface_declaration :
    interface_csv_declaration
    | interface_file_declaration 
    {
       throw VhdlNotYetException(NotYetReason("Interface File Declaration"),VhdlFilePosition(@1));
    }
    ;
    
interface_csv_declaration :
	opt_object_class identifier_list LEX_V_DDOT opt_mode subtype_indication
	opt_bus opt_assigment
	{  
	 pInterfaceList list= new InterfaceList();
	 InterfaceDecl* id;
	 for(IdentifierList::iterator it = $2->begin(); it != $2->end(); ++it ){
	     id = new InterfaceDecl((*it),$1,$4,$5);
	     list->push_back( *id );
   }
   delete $2;
   $$= list; 
  }
	;
	
opt_object_class :
	/* NOTHING */ { $$ = O_NONE; }
	| object_class
	;

object_class:
	LEX_V_CONSTANT   { $$ = O_CONSTANT;}
    | LEX_V_SIGNAL   { $$ = O_SIGNAL; } 
    | LEX_V_VARIABLE  { $$ = O_VARIABLE; }
    ;
    

opt_assigment :
    /* NOTHING */
    | LEX_V_ASSIGN  expression 
    {
      delete $2;
       throw VhdlNotYetException(NotYetReason("Initialization"),VhdlFilePosition(@1));
     }
    ;
    
    
opt_mode:
    /* NOTHING */ { $$ = M_UNKNOWN; }
    | mode
    ;
    
mode :
    LEX_V_IN { $$ = M_IN;}
    | LEX_V_OUT { $$ = M_OUT;}
    | LEX_V_INOUT { $$ = M_INOUT;}
    | LEX_V_BUFFER { $$ = M_BUFFER;}
    | LEX_V_LINKAGE { $$ = M_LINKAGE;}
    ;


interface_file_declaration :
    LEX_V_FILE identifier_list LEX_V_DDOT subtype_indication 
    { 
     $$ = NULL;
    }
    ;
    

    
////////////////////////
// ASSOCIATION LIST
///////////////////////  



association_list :
    LEX_V_LPAR association_element association_list_rest LEX_V_RPAR
    {  
        if($3){
          $3->push_front($2);
          $$ = $3;
        }
        else {
          pGenAssocList list = new GenAssocList;
          list->push_front($2);
          $$ = list;
        }
      }
    ;


association_list_rest :
    /* NOTHING */ { $$=NULL;}
    | association_list_rest LEX_V_COMMA association_element
      {
        if($1){
          $1->push_back($3);
          $$ = $1; 
        } 
        else {
          pGenAssocList list = new GenAssocList;
          list->push_front($3);
          $$ = list;        
        }
      }
    ;	
 
    
gen_association_list :
    LEX_V_LPAR gen_association_element gen_association_list_rest LEX_V_RPAR
      {  
        if($3){
          $3->push_front($2);
          $$ = $3;
        }
        else {
          pGenAssocList list = new GenAssocList;
          list->push_front($2);
          $$ = list;
        }
        
      }
    ;

    
gen_association_list_rest :
    /* NOTHING */ {  $$ = NULL; }
    | gen_association_list_rest LEX_V_COMMA gen_association_element
      {
  
        if($1){
          $1->push_back($3);
          $$ = $1; 
        } 
        else {
          pGenAssocList list = new GenAssocList;
          list->push_front($3);
          $$ = list;        
        }
      }
    ;
    
    
association_element :
    formal_part LEX_V_ASR actual_part
    { 
      $$ = new NamedAssocElem($3,$1);
    }
   | actual_part 
    {
      $$ = new NamedAssocElem($1);
    }
    ;
   
gen_association_element:
    	association_element 
    | 	discrete_range1 {  $$ = $1; }
    ;
    
formal_part :
    name
    ;
    
actual_part :
   /* expression */ // original grammar rule
    name {  $$ = new NameExpr($1); }
    | LEX_V_LITABSTR{ $$  = new LiteralExpr($1); } 
    | LEX_V_OPEN { $$ = new NameExpr(new SigName(StringToken("open",@1))); }
    ;
    
////////////////////////
// SENSITIVITY LIST
///////////////////////        
  
sensitivity_list :
    signal_name sensitivity_list_rest
    ;
    
sensitivity_list_rest :
    /* NOTHING */
    | sensitivity_list_rest LEX_V_COMMA signal_name
    ;
    
signal_name :
    name { delete $1; }
    ;
  
    
///////////////////////////////////
// Primary unit - CONFIGURATION 
//////////////////////////////////

configuration_declaration :
    LEX_V_CONFIGURATION LEX_V_IDENT LEX_V_OF entity_name LEX_V_IS
          configuration_declarative_part
          block_configuration 
    LEX_V_END opt_configuration_end LEX_V_SEMICOL
    {
      delete $2;
    }
    ;
    
configuration_declarative_part :
    /* NOTHING */
    | configuration_declarative_part configuration_declarative_item 
    ;

configuration_declarative_item :
    use_clause
    | attribute_specification
    | group_declaration
    ;
    
block_configuration :
    LEX_V_FOR name
          opt_use_clauses
          opt_configuration_items 
    LEX_V_END LEX_V_FOR LEX_V_SEMICOL
    {
      delete $2;
    }
    ;
    
    
opt_use_clauses :
    /* NOTHING */
    | opt_use_clauses use_clause
    ;
    
opt_configuration_items :
    /* NOTHING */
    | opt_configuration_items configuration_item
    ;
    
configuration_item :
    block_configuration
    | component_configuration
    ;
    
component_configuration :
    LEX_V_FOR component_specification
          opt_binding_indication 
          opt_block_configuration 
    LEX_V_END LEX_V_FOR LEX_V_SEMICOL
    ;
    
component_specification :
    instantiation_list LEX_V_DDOT mark
    {
      delete $3;
    }
    ;
    
instantiation_list :
    LEX_V_IDENT instantiation_list_rest { delete $1; }
    | LEX_V_OTHERS
    | LEX_V_ALL
    ;
    
instantiation_list_rest :
    /* NOTHING */
    | instantiation_list_rest LEX_V_COMMA LEX_V_IDENT { delete $3; }
    ;


    
opt_binding_indication  :
    /* NOTHING */
    | binding_indication LEX_V_SEMICOL
    ;
    
opt_block_configuration  :
    /* NOTHING */
    | block_configuration
    ;
    
opt_configuration_end :
     opt_configuration opt_ident 
    ;
    
    
///////////////////////////////////
// Primary unit - PACKAGE
//////////////////////////////////

package_declaration :
    LEX_V_PACKAGE 

    LEX_V_IDENT LEX_V_IS
          package_declarative_part 
    LEX_V_END opt_package_end LEX_V_SEMICOL
    {
      delete $2;
    }
    ;

package_declarative_part :
    /* NOTHING */
    | package_declarative_part package_declarative_item 
    ;

package_declarative_item :
    subprogram_declaration
    | type_declaration
    | subtype_declaration
    | constant_declaration
    | signal_declaration { delete $1; }
    | shared_variable_declaration
    | file_declaration
    | alias_declaration
    | component_declaration
    | attribute_declaration
    | attribute_specification
    | disconnection_specification
    | use_clause
    | group_template_declaration
    | group_declaration
    ;
    
opt_package_end :
    opt_package opt_package_simple_name
    ;

opt_package_simple_name :
    /* NOTHING */
    | package_simple_name
    ;

package_simple_name :
    name { delete $1; }
    ;

//////////////////////////////////////
// Secondary unit - ARCHITECTURE BODY
/////////////////////////////////////

architecture_body :
    LEX_V_ARCHITECTURE LEX_V_IDENT LEX_V_OF entity_name LEX_V_IS
    {
      driver.client_->haveArch(StringToken(*$2,@2),*$4);
      delete $2;
      delete $4;
    
    }
          architecture_declarative_part 
    LEX_V_BEGIN
          architecture_statement_part 
    LEX_V_END opt_arch_end LEX_V_SEMICOL
     {
      driver.client_->endArch();
    }
    ;
    
architecture_declarative_part :
    /* NOTHING */
    | architecture_declarative_part block_declarative_item 
    ;
    
block_declarative_item :
    subprogram_declaration
    {
       throw VhdlNotYetException(NotYetReason("subprogram declaration"),VhdlFilePosition(@1));
     }
    | subprogram_body
    {
       throw VhdlNotYetException(NotYetReason("subprogram body"),VhdlFilePosition(@1));
     }
    | type_declaration
    {
       throw VhdlNotYetException(NotYetReason("type declaration"),VhdlFilePosition(@1));
     }
    | subtype_declaration
    {
       throw VhdlNotYetException(NotYetReason("subtype declaration"),VhdlFilePosition(@1));
     }
    | constant_declaration
    {
       throw VhdlNotYetException(NotYetReason("constant declaration"),VhdlFilePosition(@1));
     }
    | signal_declaration 
    { 
      for(InterfaceList::iterator i=$1->begin(); i != $1->end(); ++i)
          driver.client_->haveSignalDeclar(*i);
        delete $1;
    }
    | shared_variable_declaration
    {
       throw VhdlNotYetException(NotYetReason("shared variable declaration"),VhdlFilePosition(@1));
     }
    | file_declaration
    {
       throw VhdlNotYetException(NotYetReason("file declaration"),VhdlFilePosition(@1));
     }
    | alias_declaration
    {
       throw VhdlNotYetException(NotYetReason("alias declaration"),VhdlFilePosition(@1));
     }
    | component_declaration
    | attribute_declaration
    {
       throw VhdlNotYetException(NotYetReason("attribute declaration"),VhdlFilePosition(@1));
     }
    | attribute_specification
    {
       throw VhdlNotYetException(NotYetReason("attribute specification"),VhdlFilePosition(@1));
     }
    | configuration_specification
    {
       throw VhdlNotYetException(NotYetReason("configuration specification"),VhdlFilePosition(@1));
     }
    | disconnection_specification
    {
       throw VhdlNotYetException(NotYetReason("disconnection specification"),VhdlFilePosition(@1));
     }
    | use_clause
    {
       throw VhdlNotYetException(NotYetReason("use clause"),VhdlFilePosition(@1));
     }
    | group_template_declaration
    {
       throw VhdlNotYetException(NotYetReason("group template declaration"),VhdlFilePosition(@1));
     }
    | group_declaration
    {
       throw VhdlNotYetException(NotYetReason("group  declaration"),VhdlFilePosition(@1));
     }
    ;
    
architecture_statement_part :
    /* NOTHING */
    | architecture_statement_part concurrent_statement 
    ;
    
opt_arch_end :
    opt_architecture opt_arch_simple_name
    ; 
    
opt_arch_simple_name :
    /* NOTHING */
    | arch_simple_name
    ;
    
arch_simple_name :
    name
    ;
    
//////////////////////////////////////
// Secondary unit - PACKAGE BODY
/////////////////////////////////////   

package_body :
    LEX_V_PACKAGE LEX_V_BODY package_simple_name LEX_V_IS
          package_body_declarative_part 
    LEX_V_END opt_package_body_terms  opt_package_simple_name  
    LEX_V_SEMICOL
    ;
    
opt_package_body_terms :
    /* NOTHING */
    | LEX_V_PACKAGE LEX_V_BODY
    ;
    
package_body_declarative_part :
    /* NOTHING */
    | package_body_declarative_part package_body_declarative_item 
    ;
    
package_body_declarative_item :
    subprogram_declaration
    | subprogram_body
    | type_declaration
    | subtype_declaration
    | constant_declaration
    | shared_variable_declaration
    | file_declaration
    | alias_declaration
    | use_clause
    | group_template_declaration
    | group_declaration
    ;
    
    
/////////////////////////////
// end of library units
/////////////////////////////

/////////////////////////////
// DECLARATIV ITEMS
/////////////////////////////

//////////////
// SUBPROGRAM
//////////////

subprogram_declaration :
    subprogram_specification LEX_V_SEMICOL
    ;
    
subprogram_specification :
    LEX_V_PROCEDURE designator opt_formal_parameter_list  

    | opt_pure_or_impure LEX_V_FUNCTION designator opt_formal_parameter_list 
      LEX_V_RETURN subtype_indication
      {
        delete $6;
      }
    ; 
    
designator :
    LEX_V_IDENT { delete $1; }
    | LEX_V_LITSTRING 
    ;
    
opt_pure_or_impure :
    /* NOTHING */
    | LEX_V_PURE
    | LEX_V_IMPURE
    ;
    
subprogram_body :
    subprogram_specification LEX_V_IS
          subprogram_declarative_part 
    LEX_V_BEGIN
          subprogram_statement_part 
    LEX_V_END opt_subprogram_kind  opt_designator  LEX_V_SEMICOL
    ;
    
opt_subprogram_kind :
    /* NOTHING */
    | subprogram_kind
    ;

subprogram_kind :
    LEX_V_PROCEDURE
    | LEX_V_FUNCTION
    ;
    
opt_designator :
    /* NOTHING */
    | designator
    ;
    
subprogram_declarative_part :
    /* NOTHING */
    | subprogram_declarative_part subprogram_declarative_item 
    ;
    
subprogram_declarative_item :
    subprogram_declaration
    | subprogram_body
    | type_declaration
    | subtype_declaration
    | constant_declaration
    | variable_declaration
    | file_declaration
    | alias_declaration
    | attribute_declaration
    | attribute_specification
    | use_clause
    | group_template_declaration
    | group_declaration
    ;
    
subprogram_statement_part:
    /* NOTHING */
    | subprogram_statement_part sequential_statement
    ;
 
////////////////////   
// TYPE DECLARATION
////////////////////

type_declaration :
    full_type_declaration
    | incomplete_type_declaration
    ;
    
full_type_declaration :
    LEX_V_TYPE LEX_V_IDENT LEX_V_IS type_definition LEX_V_SEMICOL
    {
      delete $2;
    }
    ;
    
incomplete_type_declaration :
    LEX_V_TYPE LEX_V_IDENT LEX_V_SEMICOL
    {
      delete $2;
    }
    ;
 

/////////////////////////////
// DEFINITIONS 
/////////////////////////////   

/////////////////////////////
// TYPE DEFINITIONS 
/////////////////////////////  
 
type_definition :
    scalar_type_definition
    | composite_type_definition 
    | access_type_definition
    | file_type_definition
    | protected_type_def
    ;
    
scalar_type_definition :
    enumeration_type_definition
    | integer_or_fl_type_def
    | physical_type_definition
    ;
    
composite_type_definition :
    array_type_definition
    | record_type_definition
    ;
    
access_type_definition :
    LEX_V_ACCESS subtype_indic_incomplete
    {
      delete $2;
    }
    ;
    
file_type_definition :
    LEX_V_FILE LEX_V_OF mark
    {
      delete $3;
    }
    ;
    
protected_type_def :
    protected_type_decl
    | protected_type_body
    ;
    
/////////////////////////////    
// Scalar types definitions
/////////////////////////////
    
enumeration_type_definition :
    LEX_V_LPAR enumeration_literal enum_lit_list LEX_V_RPAR
    ;
  
enum_lit_list :  
    /* NOTHING */
    | LEX_V_COMMA enumeration_literal enum_lit_list 
    ;
    

    
integer_or_fl_type_def :
    range_constraint { delete $1; }
    ;
        
physical_type_definition :
    range_constraint
    LEX_V_UNITS
      primary_unit_declaration
      opt_secondary_unit_declaration  
    LEX_V_END LEX_V_UNITS  opt_physical_type_simple_name
    {
      delete $1;
    }
    ;

primary_unit_declaration :
    LEX_V_IDENT  LEX_V_SEMICOL { delete $1; }
    ;  
    
opt_secondary_unit_declaration :
    /* NOTHING */
    | opt_secondary_unit_declaration secondary_unit_declaration
    ;
    
secondary_unit_declaration :
   LEX_V_IDENT LEX_V_EQUAL physical_lit LEX_V_SEMICOL
   {
    delete $1;
   }
    ;
    
opt_physical_type_simple_name :
    /* NOTHING */
    | physical_type_simple_name 
    ;
    
physical_type_simple_name :
    name { delete $1; }
    ;
    
////////////////////////////////    
// Composite types definitions
////////////////////////////////
    
array_type_definition :
    unconstrained_array_definition 
    | constrained_array_definition
    ;
    
unconstrained_array_definition :
    LEX_V_ARRAY LEX_V_LPAR index_subtype_defs  LEX_V_RPAR
        LEX_V_OF element_subtype_indication 
    ;
    
index_subtype_defs :
    index_subtype_definition opt_more_index_subtype_defs
    ;
    
opt_more_index_subtype_defs :
    /* NOTHING */
    |  LEX_V_COMMA index_subtype_definition opt_more_index_subtype_defs
    ;

index_subtype_definition:
	 mark LEX_V_RANGE LEX_V_RHOMB { delete $1; }
  ;

element_subtype_indication :
    subtype_indication {delete $1; }
    ;
    
constrained_array_definition :
    LEX_V_ARRAY index_constraint LEX_V_OF element_subtype_indication

    ;
    
record_type_definition :
    LEX_V_RECORD
          element_declaration
          opt_element_declaration  
    LEX_V_END LEX_V_RECORD opt_record_end
    ;
    
element_declaration :
    identifier_list LEX_V_DDOT element_subtype_definition LEX_V_SEMICOL
    {
      delete $1;
    }
    ;
    
opt_element_declaration :
    /* NOTHING */
    | element_declaration opt_element_declaration 
    ;
  
element_subtype_definition :
    subtype_indication { delete $1; }
    ;
    
opt_record_end :
    /* NOTHING */
    | record_end 
    ;

record_end :
    name { delete $1; }
    ;
    
////////////////////////////////    
// Protected type definitions
////////////////////////////////
    
protected_type_def :
    LEX_V_PROTECTED protected_type_def_2
    ;

protected_type_def_2:
    protected_type_decl
    | protected_type_body
    ;
    
protected_type_decl :
          protected_type_declarative_part 
    LEX_V_END LEX_V_PROTECTED opt_protected_type_declar_end
    ;
    
protected_type_body :
     LEX_V_BODY
          protected_type_body_declarative_part 
    LEX_V_END LEX_V_PROTECTED LEX_V_BODY opt_protected_type_declar_end
    ;

opt_protected_type_declar_end :
    /* NOTHING */
    | protected_type_simple_name 
    ;
    
protected_type_simple_name :
    name {delete $1; }
    ;
    
protected_type_declarative_part :
    /* NOTHING */
    | protected_type_declarative_part protected_type_declarative_item 
    ;
    
protected_type_declarative_item :
    subprogram_specification
    | attribute_specification
    | use_clause
    ;
    
protected_type_body_declarative_part :
    /* NOTHING */
    |  protected_type_body_declarative_part protected_type_body_declarative_item 
    ;
    
protected_type_body_declarative_item :
    subprogram_declaration
    | subprogram_body
    | type_declaration
    | subtype_declaration
    | constant_declaration
    | variable_declaration
    | file_declaration
    | alias_declaration
    | attribute_declaration
    | attribute_specification
    | use_clause
    | group_template_declaration
    | group_declaration
    ;
    
///////////////////////
// SUBTYPE DECLARATION
//////////////////////

subtype_declaration :
    LEX_V_SUBTYPE LEX_V_IDENT LEX_V_IS subtype_indication LEX_V_SEMICOL
    {
      delete $2;
      delete $4;
    }
    ;
    
subtype_indication :
    subtype_indic_incomplete
    ;
    
subtype_indic_incomplete :
    mark  opt_index_constraint 
    {
      if(!$2){
        if( (*$1) == "std_logic"){
          $$ = new SimpleType(*$1);
        } else { 
          throw VhdlOthException(OthReason("Unknown type",*$1,""),VhdlFilePosition(@1),CircCtx());
        }  
      } else {
        if( (*$1) == "std_logic_vector"){
          if($2->size()>1 ){
             throw VhdlOthException(OthReason("Index constraint does not correspond to the array type",*$1,""),
           VhdlFilePosition(@1),CircCtx());
          }
          $$ = new ArrayType(*$1,*$2);
        } else { 
           throw VhdlOthException(OthReason("Unknown type",*$1,""),VhdlFilePosition(@1),CircCtx());
        }  
      delete $1;
      delete $2;
      }
      
    
    }
    | subtype_indication_1
    ;
    
subtype_indication_1 :
    mark mark range_constraint 
    {
      delete $1;
      delete $2;
      delete $3;
       throw VhdlNotYetException(NotYetReason("Subtype Indication"),VhdlFilePosition(@1));
    }
    | mark range_constraint  {
        
       if( (*$1) == "std_logic_vector"){
          pGenAssocList list = new GenAssocList;
          list->push_front($2);
          $$ = new ArrayType(*$1,*list);
        } else { 
           throw VhdlOthException(OthReason("Unknown type",*$1,""),VhdlFilePosition(@1),CircCtx());
        }  
    }
    | mark mark opt_index_constraint 
     {
      delete $1;
      delete $2;
      delete $3;
       throw VhdlNotYetException(NotYetReason("Subtype Indication"),VhdlFilePosition(@1));
    }

    ;
    

    
opt_index_constraint:
    /* NOTHING */ { $$ = NULL; }
   | gen_association_list 
   {
    for( GenAssocList::iterator i = $1->begin(); i!=$1->end(); ++i ){
      RangeAssocElem* range = dynamic_cast <RangeAssocElem*> (*i);
        if(range){

        } else 
        { 
           throw VhdlOthException(OthReason("Error in index constraint","",""),VhdlFilePosition(@1),CircCtx());
        }  
      }
        $$ = $1;
    }
    ;
    

range_constraint :
    LEX_V_RANGE range_2 { $$ = $2; }
    ;
    
  

    
range :
    attribute_name_with_param
    | simple_expression direction simple_expression
    ;
    
range_2 :
   /* expression direction expression */ 
   LEX_V_LITABSTR direction LEX_V_LITABSTR 
   {
      RangeAssocElem* range = new RangeAssocElem($1,$3,$2);
      if(!range->validate()) { 
           throw VhdlOthException(OthReason("Wrong range","",""),VhdlFilePosition(@1),CircCtx());
        }  
      $$ = range;
    }
    ; 
    
      
direction :
    LEX_V_TO { $$ = D_TO; }
    | LEX_V_DOWNTO { $$ = D_DOWNTO ; }
    ;
    
index_constraint :
    LEX_V_LPAR discrete_range opt_discrete_ranges LEX_V_RPAR 
    ;
    
opt_discrete_ranges :
      /* NOTHING */
    | opt_discrete_ranges LEX_V_COMMA discrete_range
    ;
    
discrete_range :
    subtype_indication 
     {
      delete $1;
       throw VhdlNotYetException(NotYetReason("Discrete Range - Subtype Indication"),VhdlFilePosition(@1));
    }
   | range  
    ;
    
discrete_range1:
	  subtype_indication_1 
	  {
      delete $1;
       throw VhdlNotYetException(NotYetReason("Discrete Range - Subtype Indication"),VhdlFilePosition(@1));
    }
   /* |	expression direction expression */
   | LEX_V_LITABSTR direction LEX_V_LITABSTR 
    {
      RangeAssocElem* range = new RangeAssocElem($1,$3,$2);
      if(!range->validate()) { 
           throw VhdlOthException(OthReason("Chybny rozsah","",""),VhdlFilePosition(@1),CircCtx());
        }  
      $$ = range;
    }
    ;
    



    
///////////////////////
// CONSTANT DECLARATION
//////////////////////

constant_declaration :
    LEX_V_CONSTANT identifier_list LEX_V_DDOT subtype_indication opt_assigment 
    LEX_V_SEMICOL
    {
      delete $2;
      delete $4;
    }
    ;
    
///////////////////////
// SIGNAL DECLARATION
//////////////////////

signal_declaration :
    LEX_V_SIGNAL identifier_list LEX_V_DDOT subtype_indication
     opt_signal_kind  opt_assigment LEX_V_SEMICOL
     {
        pInterfaceList list= new InterfaceList();
	      InterfaceDecl* id;
	      for(IdentifierList::iterator it = $2->begin(); it != $2->end(); ++it ){
	       id = new InterfaceDecl((*it),O_NONE,M_UNKNOWN,$4);
	       list->push_back( *id );
        }
        delete $2;
        $$= list; 
     }
     ;
     
opt_signal_kind :
    /* NOTHING */
    | signal_kind
    ;

signal_kind :
    LEX_V_REGISTER
    | LEX_V_BUS
    ;
    
 ////////////////////////
 // VARIABLE DECLARATION
 ////////////////////////  
 
shared_variable_declaration :
    variable_declaration
    ;
    
variable_declaration :
    opt_shared LEX_V_VARIABLE identifier_list 
    LEX_V_DDOT  subtype_indication opt_assigment LEX_V_SEMICOL
    {
      delete $3;
      delete $5;
    }
    ;
    
////////////////////////
// FILE DECLARATION
////////////////////////  

file_declaration :
    LEX_V_FILE identifier_list LEX_V_DDOT
    subtype_indication opt_file_open_information LEX_V_SEMICOL
    {
      delete $2;
      delete $4;
    }
    ;
    
opt_file_open_information :
    /* NOTHING */
    | file_open_information
    ;

file_open_information :
    opt_file_open_kind LEX_V_IS file_logical_name
    ;
    
opt_file_open_kind :
    /* NOTHING */
    | open_file_open_kind
    ;
   
open_file_open_kind :
    LEX_V_OPEN file_open_kind_expression 
    ; 

file_open_kind_expression :
    expression { delete $1; }
    ;
    
file_logical_name :
    string_expression
    ;
    
string_expression :
    expression { delete $1; }
    ;
    
////////////////////////
// ALIAS DECLARATION
//////////////////////// 

alias_declaration :
    LEX_V_ALIAS alias_designator opt_subtype_indication 
    LEX_V_IS name  signature  LEX_V_SEMICOL
    {
      delete $5;
    }
    ;
    
opt_subtype_indication :
    /* NOTHING */
    | LEX_V_DDOT subtype_indication 
    {
      delete $2;
    }
    ;
    
alias_designator :
    LEX_V_IDENT { delete $1; }
    | LEX_V_LITCHAR
    | LEX_V_LITSTRING
    ;
    

    
signature :
    /* NOTHING */
    | LEX_V_SLPAR mark type_mark_list  opt_return_type_mark LEX_V_SRPAR
    {
      delete $2;
    }
    | LEX_V_SLPAR LEX_V_RETURN mark LEX_V_SRPAR 
    {
      delete $3;
    }
    ;
    
    
type_mark_list :
    /* NOTHING */
    | type_mark_list  LEX_V_COMMA mark 
    {
      delete $3;
    }
    ;

opt_return_type_mark :
    /* NOTHING */
    | LEX_V_RETURN mark 
    {
      delete $2;
    }
    ;
 
////////////////////////
// ATRIBUTE DECLARATION
////////////////////////
   
attribute_declaration :
    LEX_V_ATTRIBUTE LEX_V_IDENT LEX_V_DDOT mark LEX_V_SEMICOL
    {
      delete $2;
      delete $4;
    }
    ;
    
attribute_specification :
    LEX_V_ATTRIBUTE attribute_designator LEX_V_OF 
    entity_specification LEX_V_IS expression LEX_V_SEMICOL
    {
      delete $6;
    }
    ;
    
attribute_designator :
    attribute_simple_name
    ;
    
attribute_simple_name :
    LEX_V_IDENT { delete $1; }
    
    ;
    
entity_specification :
    entity_name_list LEX_V_DDOT entity_class
    ;
    
entity_name_list :
    entity_designator_list
    | LEX_V_OTHERS
    | LEX_V_ALL
    ;
    
entity_designator_list :  
    entity_designator
    | entity_designator_list LEX_V_COMMA entity_designator
    ;
    
entity_designator :
    entity_tag /* signature */
    ;

entity_tag :
    LEX_V_IDENT { delete $1; }
    | LEX_V_LITCHAR
    | LEX_V_LITSTRING
    ;
    
entity_class :
    LEX_V_ENTITY
    | LEX_V_ARCHITECTURE
    | LEX_V_CONFIGURATION
    | LEX_V_PROCEDURE
    | LEX_V_FUNCTION
    | LEX_V_PACKAGE
    | LEX_V_TYPE
    | LEX_V_SUBTYPE
    | LEX_V_CONSTANT
    | LEX_V_SIGNAL
    | LEX_V_VARIABLE
    | LEX_V_COMPONENT
    | LEX_V_LABEL
    | LEX_V_LITERAL
    | LEX_V_UNITS
    ;
    
entity_class_entry :
    entity_class opt_rhomb
    ;
    
///////////////////////////////
// DISCONNESTION SPECIFICATION
///////////////////////////////

disconnection_specification :
    LEX_V_DISCONNECT guarded_signal_specification 
    LEX_V_AFTER expression LEX_V_SEMICOL
    {
      delete $4;
    }
    ;
    
guarded_signal_specification :
    guarded_signal_list LEX_V_DDOT mark
    {
      delete $3;
    }
    ;
    
guarded_signal_list :
    signal_list
    ;
    
signal_list :
    signal_name_list
    | LEX_V_OTHERS
    | LEX_V_ALL
    ;
    
signal_name_list :
    name_list
    ;
    

    
///////////////////////////////
// GROUP (TEMPLATE) DECLARATION
///////////////////////////////
  
group_template_declaration :
    LEX_V_GROUP LEX_V_IDENT LEX_V_IS 
    LEX_V_LPAR entity_class_entry_list LEX_V_RPAR 
    LEX_V_SEMICOL
    {
      delete $2;
    }
    ;
    
group_declaration :
    LEX_V_GROUP LEX_V_IDENT LEX_V_DDOT 
    LEX_V_IDENT
    LEX_V_LPAR  group_constituent_list  LEX_V_RPAR 
    LEX_V_SEMICOL
    {
      delete $2;
      delete $4;
    }
    ;
    

    
group_constituent_list :
    group_constituent group_constituent_list_2
    ;

group_constituent_list_2 :
    /* NOTHING */ 
    | group_constituent_list_2 LEX_V_COMMA group_constituent 
    ;
    
group_constituent :
    LEX_V_LITCHAR 
    | mark { delete $1; }
    ;
    

    
///////////////////////////////
// COMPONENT DECLARATION
///////////////////////////////
    
component_declaration :
    LEX_V_COMPONENT 
     LEX_V_IDENT opt_is 
          {
            driver.client_->haveComponent(StringToken(*$2,@2));
            delete $2;
          }
          opt_local_generic_clause 
          opt_local_port_clause 
    LEX_V_END LEX_V_COMPONENT opt_component_end 
    LEX_V_SEMICOL
    {
      driver.client_->endComponent(*$9);
      delete $9;
    }
    ;
    
opt_local_generic_clause :
    /* NOTHING */ 
    | local_generic_clause
    ;

local_generic_clause :
    generic_clause
    ;
    
opt_local_port_clause :
    /* NOTHING */ 
    | local_port_clause
     {   
        for(InterfaceList::iterator i=$1->begin(); i != $1->end(); ++i)
          driver.client_->haveComponentPort(*i);
        delete $1;     
     }
    ;
    
local_port_clause :
    port_clause
    ;
    
opt_component_end :
    /* NOTHING */ {$$ = new StringToken("");}
    | component_simple_name 
    ;
    
component_simple_name :
    LEX_V_IDENT 
    {
      $$ =  new StringToken(*$1,@1);
    }
    ;
    
///////////////////////////////
// CONFIGURATION SPECIFICATION
//////////////////////////////

configuration_specification :
    LEX_V_FOR component_specification binding_indication  LEX_V_SEMICOL
    ;
    
binding_indication :
    opt_use_entity_aspect
    opt_generic_map_aspect 
    opt_port_map_aspect 
    {
      delete $3;
    }
    ;
    
opt_use_entity_aspect :
    /* NOTHING */
    | LEX_V_USE entity_aspect
    ;
    
entity_aspect :
    LEX_V_ENTITY simple_sel_name opt_architecture_identifier { delete $3; }
    | LEX_V_CONFIGURATION mark { delete $2; }
    | LEX_V_OPEN
    ;
    
////////////////////////////
// END OF DECLARATIVE ITEMS
////////////////////////////

////////////////////////////
// STATEMENTS
///////////////////////////

concurrent_statements :
    /* NOTHING */
    | concurrent_statements concurrent_statement
    ;
    
concurrent_statement:
        {
          delete driver.Label;
          driver.Label = new StringToken("");
        }
        concurrent_statement_1
    ;

concurrent_statement_1 :
    concurrent_stat_without_label
    |   concurrent_stat_with_label
    ;
 
concurrent_stat_with_label:
    LEX_V_IDENT LEX_V_DDOT 
      {
        delete driver.Label;
        driver.Label = new StringToken(*$1,@1);
      }
    concurrent_stat_with_label_1
    ;    
    
concurrent_stat_without_label:
    	concurrent_assertion_statement
    	{
       throw VhdlNotYetException(NotYetReason("concurrent assertion statement"),VhdlFilePosition(@1));
     }
    |	concurrent_procedure_call_statement
    	{
       throw VhdlNotYetException(NotYetReason("concurrent procedure call statement"),VhdlFilePosition(@1));
     }
    |	concurrent_signal_assignment_statement
    |	process_statement
    {
       throw VhdlNotYetException(NotYetReason("process statement"),VhdlFilePosition(@1));
     }
    | LEX_V_POSTOPENED process_statement
    	{
       throw VhdlNotYetException(NotYetReason("process statement"),VhdlFilePosition(@1));
     }
    | LEX_V_POSTOPENED concurrent_procedure_call_statement
    	{
       throw VhdlNotYetException(NotYetReason("concurrent peocedure call statement"),VhdlFilePosition(@1));
     }
    | LEX_V_POSTOPENED concurrent_assertion_statement
    	{
       throw VhdlNotYetException(NotYetReason("concurrent assertion statement"),VhdlFilePosition(@1));
     }
    |	LEX_V_POSTOPENED concurrent_signal_assignment_statement
    ;

concurrent_stat_with_label_1:
	block_statement
		{
       throw VhdlNotYetException(NotYetReason("block statement"),VhdlFilePosition(@1));
     }
    |	component_instantiation_statement
    | concurrent_assertion_statement
    {
       throw VhdlNotYetException(NotYetReason("concurrent assertion statement"),VhdlFilePosition(@1));
     }
    |	concurrent_procedure_call_statement
    	{
       throw VhdlNotYetException(NotYetReason("concurrent procedure call statement"),VhdlFilePosition(@1));
     }
    |	concurrent_signal_assignment_statement
    |	generate_statement
    	{
       throw VhdlNotYetException(NotYetReason("generate statement"),VhdlFilePosition(@1));
     }
    |	process_statement
    	{
       throw VhdlNotYetException(NotYetReason("process statement"),VhdlFilePosition(@1));
     }
    | LEX_V_POSTOPENED process_statement
    	{
       throw VhdlNotYetException(NotYetReason("process statement"),VhdlFilePosition(@1));
     }
    | LEX_V_POSTOPENED concurrent_procedure_call_statement
    	{
       throw VhdlNotYetException(NotYetReason("concurrent procedure call statement"),VhdlFilePosition(@1));
     }
    | LEX_V_POSTOPENED concurrent_assertion_statement
    	{
       throw VhdlNotYetException(NotYetReason("concurrent assertion statement"),VhdlFilePosition(@1));
     }
    |	LEX_V_POSTOPENED concurrent_signal_assignment_statement
    ;




    
///////////////////
// BLOCK STATEMENT
//////////////////    

block_statement : 
    LEX_V_BLOCK   opt_guard_expression  opt_is 
        block_header
        block_declarative_part 
        LEX_V_BEGIN
        block_statement_part LEX_V_END LEX_V_BLOCK opt_ident  
    LEX_V_SEMICOL
    ; 
    
    
opt_guard_expression :
    /* NOTHING */
    | LEX_V_LPAR guard_expression LEX_V_RPAR
    ;
    
guard_expression :
    expression { delete $1; }
    ;
    
block_header :
    opt_block_header_p1
    opt_block_header_p2
    
    ;
    
opt_block_header_p1 :
    /* NOTHING */
    | generic_clause opt_generic_map_aspect LEX_V_SEMICOL
    ;
    
opt_generic_map_aspect :
    /* NOTHING */
    | generic_map_aspect 
    ;
    
opt_block_header_p2 :
    /* NOTHING */
    | port_clause opt_port_map_aspect LEX_V_SEMICOL 
    {
      delete $1;
    }
    ;
    
opt_port_map_aspect :
    /* NOTHING */  { $$ = NULL; }
    | port_map_aspect 
    ;
    
block_declarative_part :
    /* NOTHING */
    | block_declarative_part block_declarative_item 
    ;
    
block_statement_part :
    /* NOTHING */
    | block_statement_part concurrent_statement 
    ;
    
/////////////////////
// PROCESS STATEMENT
/////////////////////

process_statement :
      LEX_V_PROCESS opt_sensitivity_list   opt_is
    process_declarative_part LEX_V_BEGIN
    process_statement_part LEX_V_END 
    opt_postopened  LEX_V_PROCESS opt_ident LEX_V_SEMICOL
    ;
    
    
opt_sensitivity_list :
    /* NOTHING */
    | LEX_V_LPAR sensitivity_list LEX_V_RPAR
    ;
    
process_declarative_part :
    /* NOTHING */
    | process_declarative_part process_declarative_item 
    ;
    
process_statement_part :
    /* NOTHING */
    | process_statement_part sequential_statement 
    ;
    
process_declarative_item :
    subprogram_declaration
    | subprogram_body
    | type_declaration
    | subtype_declaration
    | constant_declaration
    | variable_declaration
    | file_declaration
    | alias_declaration
    | attribute_declaration
    | attribute_specification
    | use_clause
    | group_template_declaration
    | group_declaration
    ;
    
///////////////////////////////////////
// CONCURRENT PROCEDURE CALL STATEMENT
///////////////////////////////////////    
    
concurrent_procedure_call_statement :
     procedure_call_statement
   ;
   

    

    
//////////////////////////////////////////
// CONCURRENT ASSERTION STATEMENT
//////////////////////////////////////////  

concurrent_assertion_statement :
      assertion LEX_V_SEMICOL
    ;
    
//////////////////////////////////////////
// CONCURRENT SIGNAL ASSIGNMENT STATEMENT
//////////////////////////////////////////  
    
concurrent_signal_assignment_statement :
     concurrent_signal_assignment_statement_2 
    ;
    
concurrent_signal_assignment_statement_2 : 
    conditional_signal_assignment
    | selected_signal_assignment 
    {
       throw VhdlNotYetException(NotYetReason("Selected Signal Assigment"),VhdlFilePosition(@1));
     }
    ;
    
conditional_signal_assignment :
    target  LEX_V_LOEQ opt_guarded delay_mechanism conditional_waveforms LEX_V_SEMICOL
    {
     driver.client_->haveSignalAssignment( $1->GenerateName() , $5 );
     delete $1;
     delete $5;
    }
    ;
    
selected_signal_assignment :
    LEX_V_WITH expression LEX_V_SELECT
          target LEX_V_LOEQ opt_guarded delay_mechanism selected_waveforms LEX_V_SEMICOL
    {
      delete $2;
      delete $4;
    }
    ; 
    

  
delay_mechanism :
    /* NOTHING */
    | LEX_V_TRANSPORT 
    {
       throw VhdlNotYetException(NotYetReason("delay mechanism: TRANSPORT"),VhdlFilePosition(@1));
     }
    | LEX_V_INERTIAL
     {
       throw VhdlNotYetException(NotYetReason("delay mechanism: INERTIAL"),VhdlFilePosition(@1));
     }
    | LEX_V_REJECT  expression LEX_V_INERTIAL 
     {
        delete $2;
       throw VhdlNotYetException(NotYetReason("delay mechanism: REJECT"),VhdlFilePosition(@1));
     }
    ;
    

    
conditional_waveforms :
    conditional_waveforms_p1
    waveform opt_when_condition {$$ = $2;}
    ;
    
conditional_waveforms_p1 :
    /* NOTHING */
    | conditional_waveforms_p1 waveform LEX_V_WHEN condition LEX_V_ELSE
     {
        delete $2;
       throw VhdlNotYetException(NotYetReason("conditional waveforms"),VhdlFilePosition(@1));
     }
    ;
    
opt_when_condition :
    /* NOTHING */
    | LEX_V_WHEN condition 
     {
       throw VhdlNotYetException(NotYetReason("when condition"),VhdlFilePosition(@1));
     }
    ;
    
selected_waveforms :
    selected_waveforms_p1
    waveform LEX_V_WHEN choices
    {
      delete $2;
    }
    ;
    
selected_waveforms_p1 :
    /* NOTHING */
    | selected_waveforms_p1 waveform LEX_V_WHEN choices LEX_V_COMMA  
    {
      delete $2;
    }
    ;

    
waveform :
    waveform_elements 
   | LEX_V_UNAFFECTED 
    {
       throw VhdlNotYetException(NotYetReason("waveform: UNAFFECTED"),VhdlFilePosition(@1));
     }
    ;
    
waveform_elements :
    waveform_element 
    | waveform_elements LEX_V_COMMA waveform_element 
     {
        delete $1; delete $3;
       throw VhdlNotYetException(NotYetReason("waveform element , waveform_element"),VhdlFilePosition(@1));
     }
    ;
    
waveform_element :
    value_expression opt_after_time_expression { $$ = $1;}
    ;
    
value_expression :
    expression 
    ;
    
opt_after_time_expression :
    /* NOTHING */
    | LEX_V_AFTER expression 
     {
        delete $2;
       throw VhdlNotYetException(NotYetReason("after time expression"),VhdlFilePosition(@1));
     }
    ;
  


    
//////////////////////////////////////////
// COMPONENT INSTANTIATION STATEMENT
//////////////////////////////////////////
   

    
component_instantiation_statement : 
    mark
	    LEX_V_GENERIC 
      LEX_V_MAP association_list
	    opt_port_map_aspect
	    LEX_V_SEMICOL
	     {
         delete $1;
         delete $4;
         delete $5;
         throw VhdlNotYetException(NotYetReason("Generic map"),VhdlFilePosition(@2));
      }
    | mark
        {
	       driver.client_->haveComponentInst( *(driver.Label) , *$1, StringToken("",@1) );
	       delete $1;
        }
	    LEX_V_PORT LEX_V_MAP association_list
	    {
        if($5){
          bool positionMap;
          int cycle = 0;
          for(GenAssocList::iterator i = $5->begin(); i!=$5->end(); ++i){
            NamedAssocElem* assoc = dynamic_cast<NamedAssocElem*>(*i);
                NameExpr* actual = dynamic_cast<NameExpr*>(assoc->actual_);
                if( cycle == 0 ){
                    positionMap = assoc->formal_ ? false : true;
                }
            
                if(positionMap){
                  if(assoc->formal_) { 
                    throw VhdlOthException(OthReason("Postion mapping expected","",""),VhdlFilePosition(@1),CircCtx());
                  } 
                  driver.client_->havePosPortAssoc( cycle , *(actual->Connect(driver.client_)) );
                } else {
                  if(!assoc->formal_) { 
                    throw VhdlOthException(OthReason("Associative mapping expected","",""),VhdlFilePosition(@1),CircCtx());
                  }  
                  driver.client_->havePortAssoc(assoc->formal_->GenerateName(),*(actual->Connect(driver.client_)) );
                } 
                
                cycle++;
          }
        }
        delete $5;
      }
	    opt_generic_map_aspect
    	LEX_V_SEMICOL
    	{
        driver.client_->endComponentInst();
      }
    | mark_with_keyword
            opt_generic_map_aspect 
            opt_port_map_aspect 
      LEX_V_SEMICOL
      {
      if($3){
          bool positionMap;
          int cycle = 0;
          for(GenAssocList::iterator i = $3->begin(); i!=$3->end(); ++i){
            NamedAssocElem* assoc = dynamic_cast<NamedAssocElem*>(*i);
                NameExpr* actual = dynamic_cast<NameExpr*>(assoc->actual_);
                if( cycle == 0 ){
                    positionMap = assoc->formal_ ? false : true;
                }
                if(positionMap){
                  if(assoc->formal_) { 
                    throw VhdlOthException(OthReason("Postion mapping expected","",""),VhdlFilePosition(@1),CircCtx());
                  }  
                  driver.client_->havePosPortAssoc( cycle , *(actual->Connect(driver.client_)) );
                } else {
                  if(!assoc->formal_) { 
                    throw VhdlOthException(OthReason("Associative mapping expected","",""),VhdlFilePosition(@1),CircCtx());
                  }  
                  driver.client_->havePortAssoc(assoc->formal_->GenerateName(),*(actual->Connect(driver.client_)) );
                } 
                cycle++;
          }
        }
        delete $3;
        driver.client_->endComponentInst();
        }
    ;
    
mark_with_keyword:
	   LEX_V_COMPONENT mark 
     { 
          delete $2; 
         throw VhdlNotYetException(NotYetReason("Component mapping"),VhdlFilePosition(@1));
    }                
    |  LEX_V_ENTITY LEX_V_IDENT opt_architecture_identifier  {
        string archName = "";
        if($3) archName = *$3;
        driver.client_->haveComponentInst( *(driver.Label) , StringToken(*$2,@2),StringToken(archName,@3) );
	       delete $2;
	       delete $3;
    
    }
    |  LEX_V_CONFIGURATION mark 
    { 
          delete $2; 
         throw VhdlNotYetException(NotYetReason("Component mapping"),VhdlFilePosition(@1));
    }
    ;
    
 
    
opt_architecture_identifier :
    /* NOTHING */ { $$ = NULL; }
    | LEX_V_LPAR LEX_V_IDENT LEX_V_RPAR { $$ = $2; }
    ;
    

//////////////////////////////////////////
// GENERATE STATEMENT
//////////////////////////////////////////    
    
generate_statement :
          generation_scheme LEX_V_GENERATE
              opt_block_declarative_items 
              concurrent_statements 
              LEX_V_END LEX_V_GENERATE opt_ident  LEX_V_SEMICOL
     ;


    

    
opt_block_declarative_items  :
    /* NOTHING */
    | block_declarative_items LEX_V_BEGIN
    ;
    
block_declarative_items :
    /* NOTHING */
    | block_declarative_items block_declarative_item
    ;
    
generation_scheme :
    LEX_V_FOR generate_parameter_specification
    | LEX_V_IF condition
    ;
    
generate_parameter_specification  :
    parameter_specification  
    ;
    
///////////////////////////////
//  SEQUENTIAL STATEMENTS
////////////////////////////////

sequence_of_statements :
    /* NOTHING */
    | sequence_of_statements sequential_statement
    ;

sequential_statement :
    wait_statement
    | assertion_statement
    | report_statement
    | signal_assignment_statement
    | variable_assignment_statement
    | procedure_call_statement
    | if_statement
    | case_statement
    | loop_statement
    | next_statement
    | exit_statement
    | return_statement
    | null_statement
    ;

//////////////////
// WAIT STATEMENT
/////////////////  
    
wait_statement :
    LEX_V_WAIT 
      opt_sensitivity_clause  
      opt_condition_clause  
      opt_timeout_clause 
    LEX_V_SEMICOL
    ;
    
opt_sensitivity_clause  :
    /* NOTHING */
    | sensitivity_clause
    ;
    
opt_condition_clause  :
    /* NOTHING */
    | condition_clause
    ;
    
opt_timeout_clause  :
    /* NOTHING */
    | timeout_clause
    ;
    
sensitivity_clause :
    LEX_V_ON sensitivity_list
    ;
    
condition_clause :
    LEX_V_UNTIL condition
    ;
    
timeout_clause :
    LEX_V_FOR expression { delete $2; }
    ;

///////////////////////
// ASSERTION STATEMENT
//////////////////////     
 
assertion_statement :
     assertion LEX_V_SEMICOL
    ;
 
assertion :
   LEX_V_ASSERT condition
    opt_report_expression 
    opt_severity_expression 
  ;
  
opt_report_expression :
    /* NOTHING */
    | LEX_V_REPORT expression { delete $2; }
    ;
    
opt_severity_expression :
    /* NOTHING */
    | LEX_V_SEVERENITY expression { delete $2; }
    ;
          
////////////////////
// REPORT STATEMENT
///////////////////  

report_statement :
  
      LEX_V_REPORT expression 
      opt_severity_expression 
    LEX_V_SEMICOL
    { delete $2; }
    ;

////////////////////////////////
// SIGNAL ASSIGNMENT STATEMENT
/////////////////////////////// 

signal_assignment_statement :
     target LEX_V_LOEQ delay_mechanism waveform LEX_V_SEMICOL
     {
      delete $1;
      delete $4;
     }
    ;
 
/////////////////////////////////
// VARIABLE ASSIGNMENT STATEMENT
/////////////////////////////////    

variable_assignment_statement :
     target LEX_V_ASSIGN expression LEX_V_SEMICOL
     {
      delete $1;
      delete $3;
     }
    ;
 
/////////////////////////////////
// PROCEDURE CALL STATEMENT
/////////////////////////////////   

procedure_call_statement :
    procedure_call_stat_without_args  
    |   procedure_call_stat_with_args  
    ;
    
procedure_call_stat_without_args:
	mark LEX_V_SEMICOL
	{
    delete $1;
  }
    ;

procedure_call_stat_with_args:
	name2 LEX_V_SEMICOL
	{
    delete $1;
  }
    ;
 
////////////////
// IF STATEMENT
////////////////   
    
if_statement :
          LEX_V_IF condition LEX_V_THEN sequence_of_statements 
          elsifs
          opt_else_part 
          LEX_V_END LEX_V_IF opt_ident  LEX_V_SEMICOL
    ;
          
elsifs :
    /* NOTHING */
   | elsifs elsif_part 
   ;
   
elsif_part : 
    LEX_V_ELSIF condition LEX_V_THEN sequence_of_statements
    ;
    
opt_else_part :
    /* NOTHING */
    | LEX_V_ELSE sequence_of_statements
    ;
    
//////////////////
// CASE STATEMENT
////////////////// 

case_statement :
  
        LEX_V_CASE expression LEX_V_IS
            case_statement_alternative
            case_statement_alternatives 
            LEX_V_END LEX_V_CASE opt_ident  LEX_V_SEMICOL
    ;
    
case_statement_alternative :
    LEX_V_WHEN choices LEX_V_ASR
      sequence_of_statements 
    ;
    
case_statement_alternatives  :
    /* NOTHING */
    | case_statement_alternatives case_statement_alternative
    ;
    
//////////////////
// LOOP STATEMENT
////////////////// 

loop_statement :
    
      opt_iteration_scheme  LEX_V_LOOP
        sequence_of_statements 
      LEX_V_END LEX_V_LOOP opt_ident LEX_V_SEMICOL
      ; 
opt_iteration_scheme :
    /* NOTHING */
    | iteration_scheme
    ;

iteration_scheme :
    LEX_V_WHILE condition
    | LEX_V_FOR loop_parameter_specification
    ;
    
loop_parameter_specification :
    parameter_specification
    ;
    
parameter_specification :
    LEX_V_IDENT LEX_V_IN discrete_range
    {
      delete $1;

    }
    ;
    
///////////////////
// NEXT STATEMENT
///////////////////
    
next_statement :
     LEX_V_NEXT opt_ident  opt_when_cond LEX_V_SEMICOL
    ;
    
opt_when_cond :
    /* NOTHING */
    | LEX_V_WHEN condition
    ;
    
///////////////////
// EXIT STATEMENT
///////////////////
    
exit_statement :
     LEX_V_EXIT opt_ident opt_when_cond LEX_V_SEMICOL
    ;
    
/////////////////////
// RETURN STATEMENT
/////////////////////
    
return_statement :
     LEX_V_RETURN opt_expression  LEX_V_SEMICOL

     ;
     
/////////////////////
// NULL STATEMENT
/////////////////////
     
null_statement :
     LEX_V_NULL LEX_V_SEMICOL
    ;

    
/////////////////////////////////
// NAMES
/////////////////////////////////
   
target :
    name
    | aggregate 
      { 
        throw VhdlNotYetException(NotYetReason("aggregate"),VhdlFilePosition(@1)); 
      }
    ;
    
name:
	 mark {  $$ = new SigName(*$1); delete $1; }
   |name2
    ;
    
mark: 
	  LEX_V_IDENT
	   {
      $$ = new StringToken(*$1,@1);
     }
    |	selected_name	
      { 
        throw VhdlNotYetException(NotYetReason("Selected name"),VhdlFilePosition(@1)); 
      }
    ;

name2:
	   LEX_V_LITSTRING	
     { 
        throw VhdlNotYetException(NotYetReason("String name"),VhdlFilePosition(@1)); 
     }    
    |	attribute_name
      { 
        throw VhdlNotYetException(NotYetReason("Attribute name"),VhdlFilePosition(@1)); 
      }  
    |	index_name
    ;  
    


selected_name:
	name LEX_V_DOT suffix   { delete $1; }
    ;

simple_sel_name:
	simple_sel_name LEX_V_DOT LEX_V_IDENT  
    |	LEX_V_IDENT			  
    ;

suffix:
	designator	    
    |	LEX_V_LITCHAR	  
    |	LEX_V_ALL	  
    ;

index_name:
	 mark gen_association_list 
   {

    $$ = new IndexName(StringToken(*$1,@1),$2); 
    delete $1;
   }  
  |	name2 
  gen_association_list 
  {
    delete $1;
    delete $2;
    throw VhdlNotYetException(NotYetReason("Name specification"),VhdlFilePosition(@1)); 
  }
    ;

attribute_name:
	   mark LEX_V_SQUOT LEX_V_IDENT { delete $1; delete $3; }
    |	name2 LEX_V_SQUOT LEX_V_IDENT { delete $1; delete $3; }
    | mark LEX_V_SQUOT LEX_V_RANGE { delete $1; }
    | name2 LEX_V_SQUOT LEX_V_RANGE { delete $1;}
    ;

attribute_name_with_param:
	attribute_name opt_attribute_param
    ;

opt_attribute_param:
	/* empty */ 
    |	LEX_V_LPAR expression LEX_V_RPAR
    {
      delete $2;
    }
    ;
    
aggregate:
	rev_element_association_list2 LEX_V_RPAR
  |	LEX_V_LPAR choices LEX_V_ASR expression LEX_V_RPAR
  {
    delete $4;
  }
    ;

rev_element_association_list2:
	 LEX_V_LPAR element_association LEX_V_COMMA element_association
    |	rev_element_association_list2 LEX_V_COMMA element_association
    ;
    
element_association:
	   choices LEX_V_ASR expression { delete $3;}
    |	expression { delete $1; }
    ;

choices:
	choice opt_more_choices
    ;

opt_more_choices:
	   /* nothing */	
    |	opt_more_choices LEX_V_VLINE choice
    ;

choice:
	   expression { delete $1; }
    |	discrete_range1 { delete $1; }
    |	LEX_V_OTHERS
    ;
    

 
allocator :
    LEX_V_NEW mark mark opt_index_association_list 
    {
      delete $2;
      delete $3;
    }
    | LEX_V_NEW mark  opt_index_association_list 
    {
      delete $2;
    }
    | LEX_V_NEW qualified_expression 
    ;
    
opt_index_association_list :
   	/* nothing */	
    |	 gen_association_list	{ delete $1; }
    ;
    
qualified_expression :
    mark LEX_V_SQUOT LEX_V_LPAR expression LEX_V_RPAR
    {
      delete $1;
      delete $4;
    }
    | mark LEX_V_SQUOT aggregate
    {
      delete $1;
    }
    ;
 
/////////////////////////////////
// EXPRESSIONS
/////////////////////////////////   

condition :
    boolean_expression  
    ;
    
boolean_expression :
    expression { delete $1; }
    ;
  
opt_expression :
    /* NOTHING */
    | expression
    ;  
  
expression :
    relation 
    | or_expr
    | xor_expr
    | and_expr
    | xnor_expr
    | relation LEX_V_NAND relation { $$ = new BinOp($1,StringToken("nand",@2),$3,BinOp::LOG);}
    | relation LEX_V_NOR relation  { $$ = new BinOp($1,StringToken("nor",@2),$3,BinOp::LOG);}
    ;

or_expr:
    relation LEX_V_OR relation { $$ = new BinOp($1,StringToken("or",@2),$3,BinOp::LOG);}
    | or_expr LEX_V_OR relation { $$ = new BinOp($1,StringToken("or",@2),$3,BinOp::LOG);}
    ;   
    
and_expr:
    relation LEX_V_AND relation { $$ = new BinOp($1,StringToken("and",@2),$3,BinOp::LOG);}
    | and_expr LEX_V_AND relation { $$ = new BinOp($1,StringToken("and",@2),$3,BinOp::LOG);}
    ; 
    
xor_expr:    
    relation LEX_V_XOR relation { $$ = new BinOp($1,StringToken("xor",@2),$3,BinOp::LOG);}
    | xor_expr LEX_V_XOR relation { $$ = new BinOp($1,StringToken("xor",@2),$3,BinOp::LOG);}
    ;   
  
xnor_expr:
    relation LEX_V_XNOR relation { $$ = new BinOp($1,StringToken("xnor",@2),$3,BinOp::LOG);}
    | xnor_expr LEX_V_XNOR relation  { $$ = new BinOp($1,StringToken("xnor",@2),$3,BinOp::LOG);}
    ;   
    
relation :
    shift_expression 
    | shift_expression LEX_V_EQUAL shift_expression { $$ = new BinOp($1,StringToken("=",@2),$3,BinOp::REL);}
    | shift_expression LEX_V_NEQ shift_expression   { $$ = new BinOp($1,StringToken("!=",@2),$3,BinOp::REL);}
    | shift_expression LEX_V_LESS shift_expression  { $$ = new BinOp($1,StringToken("<",@2),$3,BinOp::REL);}
    | shift_expression LEX_V_LOEQ shift_expression  { $$ = new BinOp($1,StringToken(">=",@2),$3,BinOp::REL);}
    | shift_expression LEX_V_GRT shift_expression   { $$ = new BinOp($1,StringToken(">",@2),$3,BinOp::REL);}
    ;
    
shift_expression :
    simple_expression 
    | simple_expression LEX_V_SLL simple_expression { $$ = new BinOp($1,StringToken("sll",@2),$3,BinOp::SHFT);}
    | simple_expression LEX_V_SRL simple_expression { $$ = new BinOp($1,StringToken("srl",@2),$3,BinOp::SHFT);}
    | simple_expression LEX_V_SLA simple_expression { $$ = new BinOp($1,StringToken("sla",@2),$3,BinOp::SHFT);}
    | simple_expression LEX_V_SRA simple_expression { $$ = new BinOp($1,StringToken("sra",@2),$3,BinOp::SHFT);}
    | simple_expression LEX_V_ROL simple_expression { $$ = new BinOp($1,StringToken("rol",@2),$3,BinOp::SHFT);}
    | simple_expression LEX_V_ROR simple_expression { $$ = new BinOp($1,StringToken("ror",@2),$3,BinOp::SHFT);}
    ; 
    

  
simple_expression :
    signed_term 
    | simple_expression LEX_V_PLUS term   { $$ = new BinOp($1,StringToken("+",@2),$3,BinOp::ADD);}
    | simple_expression LEX_V_MINUS term  { $$ = new BinOp($1,StringToken("-",@2),$3,BinOp::ADD);}
    | simple_expression LEX_V_AMPER term  { $$ = new BinOp($1,StringToken("&",@2),$3,BinOp::ADD);}
    ;
    
    
signed_term:
    term 
    | LEX_V_MINUS term { $$ = new UnOp($2,StringToken("-",@1));}
    | LEX_V_PLUS term  { $$ = new UnOp($2,StringToken("+",@1));}
    ;
    

term :
    factor 
    | term  LEX_V_ASTER factor { $$ = new BinOp($1,StringToken("*",@2),$3,BinOp::MULT);}
    | term  LEX_V_SLASH factor { $$ = new BinOp($1,StringToken("/",@2),$3,BinOp::MULT);}
    | term LEX_V_MOD factor  { $$ = new BinOp($1,StringToken("mod",@2),$3,BinOp::MULT);}
    | term LEX_V_REM factor { $$ = new BinOp($1,StringToken("rem",@2),$3,BinOp::MULT);}
    ;
    
    
factor :
    primary 
    | primary LEX_V_POWER primary { $$ = new BinOp($1,StringToken("power",@2),$1,BinOp::MULT);}
    | LEX_V_ABS primary { $$ = new UnOp($2,StringToken("abs",@1));}
    | LEX_V_NOT primary { $$ = new UnOp($2,StringToken("not",@1));}
    ;

primary :
    name { $$ = new NameExpr($1); }
    | literal 
    | aggregate 
    {
       throw VhdlNotYetException(NotYetReason("Expression - aggregate"),VhdlFilePosition(@1));
     }
    | qualified_expression 
    {
       throw VhdlNotYetException(NotYetReason("Expression - qualified"),VhdlFilePosition(@1));
     }
    | allocator  
    {
       throw VhdlNotYetException(NotYetReason("Expression - allocator"),VhdlFilePosition(@1));
     }
    | LEX_V_LPAR expression LEX_V_RPAR { $$ = $2; }  
    ;
    
literal :
     LEX_V_LITABSTR { $$  = new LiteralExpr($1);  }
    | LEX_V_LITCHAR 
     { $$  = new LiteralExpr( $1 - 48 );  }
    | LEX_V_NULL 
    {
       throw VhdlNotYetException(NotYetReason("Expression - token NULL"),VhdlFilePosition(@1));
     }
    | LEX_V_LITBITSTR 
    {
       throw VhdlNotYetException(NotYetReason("Expression - bit string literal"),VhdlFilePosition(@1));
     }
    | physical_literal_no_def 
    {
       throw VhdlNotYetException(NotYetReason("Expression - physical literal"),VhdlFilePosition(@1));
     }
    ;
    
physical_literal_no_def :
    LEX_V_LITABSTR LEX_V_IDENT
    {
      delete $2;
    }
    ;
   
    
enumeration_literal :
    LEX_V_IDENT 
    | LEX_V_LITCHAR
    ;
    
/////////////////////////////////////////
// skip rules
/////////////////////////////////////////

skip_selected_name:
	skip_mark LEX_V_DOT skip_suffix   
    ;
    
skip_mark: 
	  LEX_V_IDENT { delete $1; }
    |	skip_selected_name	
    ;

skip_suffix:
	skip_designator	    
    |	LEX_V_LITCHAR	  
    |	LEX_V_ALL	  
    ;
    
skip_designator :
    LEX_V_IDENT { delete $1; }
    | LEX_V_LITSTRING 
    ;

 
%%

void
yy::VhdlBisonParser::error (const yy::VhdlBisonParser::location_type& l,
                          const std::string& m)
{
  throw VhdlSyntaxException (
				  VhdlSyntaxReason(m), 
				  VhdlFilePosition(l));
	   
}

