/******************************************************************************
 *
 * Copyright (C) 1997-2013 by Dimitri van Heesch.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation under the terms of the GNU General Public License is hereby 
 * granted. No representations are made about the suitability of this software 
 * for any purpose. It is provided "as is" without express or implied warranty.
 * See the GNU General Public License for more details.
 *
 * Documents produced by Doxygen are derivative works derived from the
 * input used in their production; they are not affected by this license.
 *
 */

/*********************************************************************************************
 * The original was a VHDL parser description to be used with GMD Compiler
 * Tool Box
 * written from:
 * Jan den Ouden, Jaap Hofstede
 * Department of Computer Science (INF/SPA)
 * University of Twente
 * PB 217, 7500 AE ENSCHEDE, The Netherlands
 * Tel: +31 53 893788
 * Email: hofstede@cs.utwente.nl
 * avail at: ftp.cs.utwente.nl in pub/src/VHDL/Grammar
 *
 * author of YACC transformation:
 * Thomas Dettmer
 * Dortmund University
 * Dept. of Computer Scienc, LS1
 * PB 500 500
 * D-44221 Dortmund (Germany)
 * Phone: +49-231-755-6464
 * e-mail: dettmer@ls1.informatik.uni-dortmund.de
 *****************************************************************
 *
 * This file is intended not to be used for commercial purposes
 * without permission of the University of Twente and permission
 * of the University of Dortmund
 *
 * NOTE THAT THERE IS NO WARRANTY FOR CORRECTNES, COMPLETENESS, SUPPORT
 * OR ANYTHING ELSE.
 *
 *******************************************************/
/******************************************************************************
 * modified for doxygen by M. Kreis
 * extended to VHDL 93/2008
 ******************************************************************************/


%{
#include <stdio.h>
#include <qcstring.h>
#include <qstringlist.h>
#include "config.h"

#ifndef YYSTYPE
typedef int YYSTYPE;
#endif

struct  YYMM
{
  int itype;
  QCString qstr;
};

 


// define struct instead of union
#define YYSTYPE YYMM

#include "membergroup.h"
#include "vhdldocgen.h"
#include "doxygen.h"
#include "searchindex.h"
#include "vhdlscanner.h"
#include "commentscan.h"
#include "entry.h"
#include "arguments.h"
#include "memberdef.h"
#include "vhdldocgen.h"

//-----------------------------variables ---------------------------------------------------------------------------


    


static VhdlContainer s_str;

static QList<Entry>instFiles;
static QList<Entry>libUse;


static int yyLineNr;
static Entry* lastCompound;
static Entry* currentCompound;
static Entry* lastEntity;
static Entry* current;
static Entry* tempEntry;
static Entry* current_root;
static QCString compSpec;
static QCString currName;
static int levelCounter;
static QCString confName;
static QCString genLabels;
static QCString lab;
static QCString forL;
static QList<VhdlConfNode> configL;


static int currP=0;

enum  { GEN_SEC=0x1, PARAM_SEC,CONTEXT_SEC,PROTECTED_SEC } ;

static int param_sec = 0;
static int parse_sec=0;


//---------------------------- functions --------------------------------------------------------------------------------

int vhdlscannerYYlex ();
void vhdlscannerYYerror (char const *);

static void addVhdlType(const QCString &name,int startLine,
                        int section,uint64 spec,
			const char* args,const char* type,
			Protection prot=Public);
static void addCompInst(char *n, char* instName,char* comp,int line);

static void newEntry();
static void initEntry(Entry *e);


static void pushLabel(QCString &,QCString&);
static QCString popLabel(QCString&);
static void addConfigureNode(const char* a,const char*b,
                         bool isRoot,bool isLeave,bool inlineConf=FALSE);
//static bool addLibUseClause(const QCString &type);
static bool isFuncProcProced();
static void initEntry(Entry *e);
static void addProto(const char *s1,const char *s2,const char *s3,
                     const char *s4,const char *s5,const char *s6);
static void createFunction(const QCString &impure,uint64 spec,
                           const QCString &fname);

static void createFlow();    

void newVhdlEntry()
{
  newEntry();
}

Entry* getCurrentVhdlEntry()
{
  return current;
}

void initVhdlParser()
{
  lastCompound=0;
  lastEntity=0;
  currentCompound=0;
  lastEntity=0;
  current_root=s_str.root;
  current=new Entry();
  initEntry(current);
  libUse.clear();
}

QList<Entry> & getVhdlInstList()
{
  return instFiles;
}

QList<Entry> & getLibUse()
{
  return libUse;
}

%}

%token
t_ABSTRLIST
t_CHARLIST
t_DIGIT
t_STRING
t_LETTER
t_ACCESS
t_AFTER
t_ALIAS
t_ALL
t_AND
t_ARCHITECTURE
t_ARRAY
t_ASSERT
t_ATTRIBUTE
t_BEGIN
t_BLOCK
t_BODY
t_BUFFER
t_BUS
t_CASE
t_COMPONENT
t_CONFIGURATION
t_CONSTANT
t_DISCONNECT
t_DOWNTO
t_ELSE
t_ELSIF
t_END
t_ENTITY
t_EXIT
t_FILE
t_FOR
t_FUNCTION
t_GENERATE
t_GENERIC
t_GUARDED
t_IF
t_IN
t_INOUT
t_IS
t_LABEL
t_LIBRARY
t_LINKAGE
t_LOOP
t_MAP
t_NAND
t_NEW
t_NEXT
t_NOR
t_NULL
t_OF
t_ON
t_OPEN
t_OR
t_OTHERS
t_OUT
t_PACKAGE
t_PORT
t_PROCEDURE
t_PROCESS
t_RANGE
t_RECORD
t_REGISTER
t_REPORT
t_RETURN
t_SELECT
t_SEVERITY
t_SIGNAL
t_SUBTYPE
t_THEN
t_TO
t_TRANSPORT
t_TYPE
t_UNITS
t_UNTIL
t_USE
t_VARIABLE
t_WAIT
t_WHEN
t_WHILE
t_WITH
t_XOR

/* new keywords */
t_IMPURE
t_PURE
t_GROUP
t_POSTPONED
t_SHARED
t_XNOR
t_SLL
t_SRA
t_SLA
t_SRL
t_ROR
t_ROL
t_UNAFFECTED
/*============== VHDL 2008 keywords   ======================= */

t_ASSUME_GUARANTEE
t_ASSUME
t_CONTEXT
t_COVER
t_DEFAULT
t_FAIRNESS
t_FORCE
t_INERTIAL
t_LITERAL
t_PARAMETER
t_PROTECTED
t_PROPERTY
t_REJECT
t_RELEASE
t_RESTRICT
t_RESTRICT_GUARANTEE
t_SEQUENCE
t_STRONG
t_VMODE
t_VPROP
t_VUNIT


/*============== VHDL binary operators 2008   ======================= */

t_SLSL
t_SRSR
t_QQ
t_QGT
t_QLT
t_QG
t_QL
t_QEQU
t_QNEQU

%nonassoc t_EQSym t_NESym t_LTSym t_LESym t_GTSym t_GESym t_QNEQU t_QEQU t_QL t_QG t_QLT  t_QGT
%left t_Plus t_Minus t_Ampersand
%left MED_PRECEDENCE
%left t_Star t_Slash t_MOD t_REM
%nonassoc t_DoubleStar t_ABS t_NOT MAX_PRECEDENCE

/* misc syms */
/*t_Space */

%token
t_Apostrophe
t_LeftParen
t_RightParen
t_Comma
t_VarAsgn
t_Colon
t_Semicolon
t_Arrow
t_Box
t_Bar
t_Dot
t_Q
t_At
t_Neg
t_LEFTBR
t_RIGHTBR
t_ToolDir

%type<qstr> designator literal enumeration_literal physical_literal physical_literal_no_default physical_literal_1
%type<qstr> lib_clause use_clause sel_list entity_decl entity_start entity_decl_2 entity_decl_1 arch_body arch_start arch_body_1
%type<qstr> config_decl config_start config_decl_2 config_decl_1 config_decl_3 package_decl package_start package_body pack_body_start package_body_2 package_body_1 common_decltve_item
%type<qstr> config_decltve_item subprog_decl subprog_body interf_list interf_element interf_element_4 interf_element_3 interf_element_2 interf_element_1 mode
%type<qstr> association_list association_list_1 association_list_2 gen_association_list gen_association_list_1 gen_association_list_2 association_element gen_association_element formal_part actual_part mark expr and_relation relation primary name name2 sel_name suffix ifts_name
%type<qstr> attribute_name aggregate element_association_list2 qualified_expr element_association choices choices_1 choices_2 choice type_decl type_decl_1 type_definition enumeration_type_definition enumeration_type_definition_1 enumeration_type_definition_2 physical_type_definition physical_type_definition_1 physical_type_definition_2 base_unit_decl secondary_unit_decl unconstrained_array_definition unconstrained_array_definition_1 unconstrained_array_definition_2 index_subtype_definition constrained_array_definition record_type_definition record_type_definition_1 record_type_definition_2 element_decl
%type<qstr> access_type_definition file_type_definition subtype_decl subtype_indic subtype_indic_1 subtype_indic1 subtype_indic1_1 range_constraint index_constraint index_constraint_1 index_constraint_2 discrete_range discrete_range1 range_spec direction constant_decl constant_decl_1 signal_decl signal_decl_2 signal_decl_1 variable_decl variable_decl_1 object_class signal_kind alias_decl file_decl file_decl_1 attribute_decl attribute_spec entity_spec entity_name_list entity_name_list_1
%type<qstr> entity_name_list_2 entity_class block_stat
%type<qstr> generate_stat generate_stat_1 procs_stat procs_stat1 procs_stat1_1 sensitivity_list sensitivity_list_1 sensitivity_list_2
%type<qstr> procedure_call_stat comp_decl comp_decl_2 comp_decl_1 block_config block_config_2 block_config_3 block_config_1 block_config_4 block_spec config_item comp_config comp_config_2 comp_config_1 config_spec binding_indic comp_spec
%type<qstr> inst_list entity_aspect idf_list procs_stat1_6
%type<qstr> t_Identifier t_StringLit t_BitStringLit t_AbstractLit t_CharacterLit tbox group_name record_type_simple_name
%type<qstr> entity_class_entry_list entity_class_entry group_constituent_list group_constituent group_declaration group_template_declaration
%type<qstr> procs_stat1_5 comp_1 mark_comp dot_name fi_dec multiplying_operator factor term adding_op
%type<qstr> simple_exp alias_spec sigma signature1 mark_stats mark_stats_1 signature
%type<qstr> protected_type_body protected_type_declaration alias_name_stat vcomp_stat comp_spec_stat procs_decltve_item
%type<qstr> sig_stat external_name absolute_pathname relative_pathname package_path_name external_pathname pathname_element_list neg_list pathname_element

%type<qstr> func_name return_is param func_prec iproc ifunc interface_subprogram_decl interface_package_decl package_instantiation_decl
%type<qstr> subprogram_instantiation_decl procs_stat1_4
%type<qstr>  context_ref  libustcont_stats   libustcont_stat  context_decl entity_decltve_item case_stat 
%type<qstr> exit_stat   if_stat loop_stat next_stat null_stat    return_stat  signal_assign_stat 
%type<qstr> variable_assign_stat  wait_stat report_statement assertion_stat_2 assertion_stat_1

%type<qstr> binding_indic_2 binding_indic_1   shift_op block_decltve_item disconnection_spec seq_stats_1 seq_stats_2 seq_stats
%type<qstr> signal_list signal_list_1 signal_list_2 seq_stat assertion_stat choice_stat choice_stat_1
%type<qstr>  case_stat_1 case_stat_2 case_stat_alternative  exit_stat_1 exit_stat_2  if_stat_2 if_stat_3 if_stat_1 loop_stat_2  loop_stat_1 loop_stat_3
%type<qstr>  next_stat_1  next_stat_2 return_stat_1   lable variable_assign_stat_1
%type<qstr>  wait_stat_1 wait_stat_2 wait_stat_3 target delay_mechanism
%type<qstr> if_generation_scheme if_scheme if_scheme_1 if_scheme_2 if_scheme_3  iteration_scheme for_scheme while_scheme concurrent_stats
%type<qstr> concurrent_stats_1 concurrent_stats_2  concurrent_stat  block_stat_5 block_stat_4 block_stat_3 block_stat_2 block_stat_1 block_stat_0
%type<qstr> generate_statement_body generation_scheme concurrent_assertion_stat concurrent_procedure_call concurrent_signal_assign_stat
%type<qstr> block_stat_6  block_stat_7 block_stat_8 condal_signal_assign  sel_signal_assign opts condal_wavefrms wavefrm wavefrm_element
%type<qstr> wavefrm_1 wavefrm_2 wavefrm_element_1 wavefrm_element_2 opts_1 opts_2 sel_wavefrms
%type<qstr>  sel_wavefrms_1 sel_wavefrms_2 gen_stat1 block_declarative_part end_stats inout_stat
%type<qstr> selected_signal_assignment comp_inst_stat                                             
 %type<qstr> conditional_signal_assignment selected_variable_assignment conditional_variable_assignment 
 %type<qstr> subprog_decltve_item subprog_body_3 subprog_body_1 procs_stat1_2 gen_assoc

%debug

// for debugging set yydebug=1
%initial-action { yydebug=0; }

%expect 3

// minimum bison version
//%required "2.2"



%%
start: design_file 
    

design_file     : design_unit_list
                    /* parse function/process/procedure for vhdlflow */
                     | procs_stat
                     | subprog_body

design_unit_list: design_unit
                | design_unit_list design_unit
                ;

designator      : t_Identifier                      { $$=$1; }
                | t_StringLit                       { $$=$1; }
                ;

literal         : t_AbstractLit                     { $$=$1; }
                | t_CharacterLit                    { $$=$1; }
                | t_BitStringLit                    { $$=$1; }
                | physical_literal_no_default       { $$=$1; }
                | t_NULL                            { $$="null"; }
                ;

enumeration_literal  : t_CharacterLit               { $$=$1; }
                     | t_Identifier                 { $$=$1; }

physical_literal     : physical_literal_1 t_Identifier  { $$=$1+" "+$2; }

physical_literal_1   : /* empty */        { $$=""; }
                     | t_AbstractLit      { $$=$1; }

physical_literal_no_default : t_AbstractLit t_Identifier   { $$=$1+" "+$2; }

idf_list : t_Identifier { $$=$1; }
         | idf_list t_Comma t_Identifier { $$=$1+","+$3; }
         ;

/*------------------------------------------
--  Desing Unit
--------------------------------------------*/

design_unit      : context_list lib_unit

context_list     :  /* empty */
                 | context_list context_item

lib_unit         : entity_decl
                 | config_decl
                 | package_decl
                 | arch_body
                 | package_body
                 | context_decl
                 | package_instantiation_decl
                 ;

context_item     : lib_clause
                 | use_clause
                 ;

lib_clause       : t_LIBRARY idf_list t_Semicolon
                 {
                   if ( parse_sec==0 && Config_getBool("SHOW_INCLUDE_FILES") )
                   {
                     addVhdlType($2,getParsedLine(t_LIBRARY),Entry::VARIABLE_SEC,VhdlDocGen::LIBRARY,$2.data(),"_library_");
                   }
                   $$="library "+$2;
                 }

use_clause : t_USE sel_list t_Semicolon
                 {
                   QStringList ql1=QStringList::split(",",$2,FALSE);
                   for (uint j=0;j<ql1.count();j++)
                   {
                     //QStringList ql=QStringList::split(".",ql1[j],FALSE);
                     QCString it=ql1[j].utf8();
                     if ( parse_sec==0 && Config_getBool("SHOW_INCLUDE_FILES") )
                     {
                       addVhdlType(it,getParsedLine(t_USE),Entry::VARIABLE_SEC,VhdlDocGen::USE,it.data(),"_use_");
                     }
                   }
                   $$="use "+$2;
                 }

sel_list    : sel_name { $$=$1; }
            | sel_list t_Comma sel_name { $$=$1+","+$3; }
            ;
/*------------------------------------------
--  Library Units
--------------------------------------------*/

entity_decl : entity_start error comp_end_dec  t_Semicolon

entity_decl : entity_start entity_decl_1 entity_decl_2
                     entity_decl_3 entity_decl_4   comp_end_dec  t_Semicolon

entity_start: t_ENTITY t_Identifier t_IS
              {
                $$=$2;
                lastEntity=current;
                lastCompound=0;
                 getParsedLine(t_ENTITY);
                addVhdlType($$,getParsedLine(t_ENTITY),Entry::CLASS_SEC,VhdlDocGen::ENTITY,0,0,Public);
               }
              ;

entity_decl_5 :   /* empty */
              |  t_Identifier
              ;
entity_decl_4 :  /* empty */
              | t_BEGIN concurrent_stats
              ;
entity_decl_3 :  /* empty */
              | entity_decl_3 entity_decl_6
              ;

entity_decl_6 : entity_decltve_item

entity_decl_2 : /* empty */  { $$=""; }
              | t_PORT { currP=VhdlDocGen::PORT; }  interf_list t_Semicolon  { currP=0; }
              ;
entity_decl_1 :  /* empty */  { $$=""; }
              | t_GENERIC { currP=VhdlDocGen::GENERIC;parse_sec=GEN_SEC; } interf_list t_Semicolon{ currP=0;parse_sec=0; }
              | t_GENERIC error t_Semicolon{ currP=0; }
              ;


arch_body     : arch_start arch_body_1 t_BEGIN concurrent_stats t_END arch_body_2 t_Semicolon {lastCompound=0;}
arch_body     : arch_start error t_END arch_body_2 t_Semicolon {lastCompound=0;}

arch_start    : t_ARCHITECTURE t_Identifier t_OF t_Identifier t_IS
                {
                  $$=$4+"::"+$2;
                  genLabels.resize(0);
                  pushLabel(genLabels,$2);
                  lastCompound=current;
                  addVhdlType($$,getParsedLine(t_ARCHITECTURE),Entry::CLASS_SEC,VhdlDocGen::ARCHITECTURE,0,0,Private);
                }
arch_body_2   : /* empty */
arch_body_2   : t_Identifier
arch_body_2   : t_ARCHITECTURE  t_Identifier
arch_body_2   : t_ARCHITECTURE

arch_body_1   : /* empty */  { $$=""; }
arch_body_1   : arch_body_1 arch_body_3

arch_body_3   :  block_decltve_item

config_decl   : config_start error  t_END config_decl_2 t_Semicolon { genLabels.resize(0); }
config_decl   : config_start config_decl_1 block_config t_END config_decl_2 t_Semicolon { genLabels.resize(0); }
                {
                  QCString k=$3;
                  QCString k2=$2;        
                  confName="";
                }


config_start  : t_CONFIGURATION t_Identifier t_OF t_Identifier t_IS
                {
                  forL.resize(0);
                  confName=$2+"::"+$4;
                  addVhdlType($2.data(),getParsedLine(t_CONFIGURATION),Entry::VARIABLE_SEC,VhdlDocGen::CONFIG,"configuration",$4.data());
                }

config_decl_2 : /* empty */     { $$=""; }
config_decl_2 : t_Identifier    
                { 
                  QCString l=$1;
                  $$=$1; 
                }
config_decl_2 : t_CONFIGURATION { $$="configuration"; }
config_decl_2 : t_CONFIGURATION t_Identifier  { $$=$2; }
config_decl_1 :  /* empty */    { $$=""; }
config_decl_1 : config_decl_1 config_decl_3   { $$=$1+" "+$2; }
config_decl_3 : config_decltve_item           { $$=$1; }

package_decl  : package_start error t_END package_decl_2 t_Semicolon
package_decl  : package_start package_decl_1 t_END package_decl_2 t_Semicolon
package_start : t_PACKAGE t_Identifier t_IS
                           {
                          lastCompound=current;
                          Entry *clone=new Entry(*current);
                         clone->section=Entry::NAMESPACE_SEC;
                         clone->spec=VhdlDocGen::PACKAGE;
                         clone->name=$2;
                         clone->startLine=s_str.iLine;
                         clone->bodyLine=s_str.iLine;
                         clone->protection=Package;
                         current_root->addSubEntry(clone);
                         addVhdlType($2,s_str.iLine,Entry::CLASS_SEC,VhdlDocGen::PACKAGE,0,0,Package);
                       }

package_decl_2     :  /* empty */
package_decl_2     : t_Identifier  { lastCompound=0; }
package_decl_2     : t_PACKAGE t_Identifier { lastCompound=0; }
package_decl_2     : t_PACKAGE { lastCompound=0; }

package_decl_1     :  /* empty */
package_decl_1    : package_decl_22
package_decl_1     : package_decl_1 package_decl_3
package_decl_3     : package_decltve_item

package_decl_22: gen_interface_list t_Semicolon
package_decl_22: gen_interface_list
package_decl_22: gen_interface_list gen_assoc_list
package_decl_22: gen_interface_list gen_assoc_list t_Semicolon

package_body    : pack_body_start error t_END package_body_2 t_Semicolon                   {lastCompound=0;}
package_body    : pack_body_start package_body_1 t_END package_body_2 t_Semicolon {lastCompound=0;}
pack_body_start : t_PACKAGE t_BODY t_Identifier t_IS
                      {
                        $$=$3;
                        lastCompound=current;
                        $$.prepend("_");
                        addVhdlType($$,getParsedLine(t_PACKAGE) ,Entry::CLASS_SEC,VhdlDocGen::PACKAGE_BODY,0,0,Protected);
                      }
package_body_2  :  /* empty */  { $$="";lastCompound=0; }
package_body_2  : t_Identifier                                            { lastCompound=0; }
package_body_2  : t_PACKAGE t_BODY                         { lastCompound=0; }
package_body_2  : t_PACKAGE t_BODY t_Identifier      { lastCompound=0; }

package_body_1  :  /* empty */  { $$=""; }
package_body_1  : package_body_1 package_body_3
package_body_3  : package_body_decltve_item


/*------------------------------------------
--  Declarative Item
--------------------------------------------*/

common_decltve_item_1: package_decl 
common_decltve_item_1: package_instantiation_decl
common_decltve_item_1: package_body
common_decltve_item_1: subprogram_instantiation_decl


common_decltve_item: type_decl{ $$=$1; }
common_decltve_item: subtype_decl{ $$=$1; }
common_decltve_item: constant_decl{  $$=$1; }
common_decltve_item: file_decl{ $$=$1; }
common_decltve_item: alias_decl{ $$=$1; }
common_decltve_item: subprog_decl{ $$=$1; }
common_decltve_item: use_clause { $$=$1; }

entity_decltve_item: common_decltve_item  { $$=$1; }
entity_decltve_item: subprog_body { $$=$1; }
entity_decltve_item: attribute_decl { $$=$1; }
entity_decltve_item: attribute_spec { $$=$1; }
entity_decltve_item: disconnection_spec { $$=$1; }
entity_decltve_item: signal_decl { $$=$1; }
entity_decltve_item: variable_decl { $$=$1; }
entity_decltve_item: group_template_declaration { $$=$1; }
entity_decltve_item: group_declaration { $$=$1; }
entity_decltve_item: common_decltve_item_1 { $$=""; }


block_decltve_item: common_decltve_item 
block_decltve_item: subprog_body 
block_decltve_item: comp_decl 
block_decltve_item: attribute_decl 
block_decltve_item: attribute_spec 
block_decltve_item: config_spec 
block_decltve_item: disconnection_spec 
block_decltve_item: signal_decl
block_decltve_item: variable_decl
block_decltve_item: group_template_declaration
block_decltve_item: group_declaration
block_decltve_item: common_decltve_item_1 { $$=""; }
block_decltve_item: tool_directive { $$=""; }

block_declarative_part: block_decltve_item
                      | block_declarative_part  block_decltve_item


package_decltve_item: common_decltve_item
package_decltve_item: comp_decl
package_decltve_item: attribute_decl
package_decltve_item: attribute_spec
package_decltve_item: disconnection_spec
package_decltve_item: signal_decl
package_decltve_item: variable_decl
package_decltve_item: group_template_declaration
package_decltve_item: group_declaration
package_decltve_item: package_decl
package_decltve_item: package_instantiation_decl
package_decltve_item: subprogram_instantiation_decl

package_body_decltve_item: common_decltve_item
package_body_decltve_item: subprog_body
package_body_decltve_item: variable_decl
package_body_decltve_item: group_template_declaration
package_body_decltve_item: group_declaration
package_body_decltve_item: attribute_decl
package_body_decltve_item: attribute_spec
package_body_decltve_item: common_decltve_item_1

subprog_decltve_item: common_decltve_item { $$=$1; }
subprog_decltve_item: subprog_body  { $$=""; }
subprog_decltve_item: attribute_decl { $$=$1; }
subprog_decltve_item: attribute_spec { $$=$1; }
subprog_decltve_item: variable_decl { $$=$1; }
subprog_decltve_item: group_template_declaration
subprog_decltve_item: group_declaration { $$=""; }
subprog_decltve_item: common_decltve_item_1 { $$=""; }

procs_decltve_item: subprog_decltve_item { $$=$1; }

config_decltve_item: attribute_spec    { $$=$1; }
config_decltve_item: use_clause        { $$=$1; }
config_decltve_item: group_declaration { $$=$1; }
config_decltve_item: t_USE t_VUNIT idf_list t_Semicolon { $$=$3; }

/*------------------------------------------
--  Subprograms
--------------------------------------------*/
func_prec: t_PURE { $$="pure"; }
func_prec: t_IMPURE { $$="impure"; }

subprog_decl: subprog_spec t_Semicolon { currP=0; }

subprog_spec: t_PROCEDURE t_Identifier
              { 
              currP=VhdlDocGen::PROCEDURE; 
              createFunction($2,currP,0); 
              tempEntry=current;
             }
              subprog_spec_1 {  newEntry(); }
subprog_spec: func_prec t_FUNCTION designator
              {
                currP=VhdlDocGen::FUNCTION;
                createFunction($1,currP,$3.data());
              }
              subprog_spec_2 t_RETURN mark
                {
                tempEntry=current;
                current->type=$7;
                newEntry();
              }

subprog_spec  :  t_FUNCTION designator
              {
                currP=VhdlDocGen::FUNCTION;
                createFunction(0,currP,$2.data());
              }
              subprog_spec_2 t_RETURN mark
              {
                tempEntry=current;
                current->type=$6;
                newEntry();

              }

subprog_spec_22: gen_interface_list
subprog_spec_22: gen_interface_list gen_assoc_list

subprog_spec_33: t_PARAMETER
                 { param_sec=PARAM_SEC; }
                 interf_list
                 { param_sec= 0; }
subprog_spec_33: { param_sec=PARAM_SEC; }
                 interf_list
                 { param_sec= 0; }

subprog_spec_2:  /* empty */
subprog_spec_2: subprog_spec_22 subprog_spec_33
subprog_spec_2: subprog_spec_33
subprog_spec_2: subprog_spec_22

subprog_spec_1: subprog_spec_2

subprog_body: subprog_spec t_IS subprog_body_1 
    {
      if ($3.data())
      {
        FlowChart::addFlowChart(FlowChart::VARIABLE_NO,$3,0);
      }
      FlowChart::addFlowChart(FlowChart::BEGIN_NO,"BEGIN",0);
    } 
    t_BEGIN seq_stats t_END subprog_body_2 t_Semicolon
    {
      tempEntry->endBodyLine=s_str.yyLineNr;
      createFlow();    
      currP=0;
    }
subprog_body: subprog_spec t_IS error  t_END subprog_body_2 t_Semicolon
    {
      currP=0;
    }
subprog_body_2:  /* empty */
subprog_body_2: designator
subprog_body_2: t_FUNCTION
subprog_body_2: t_PROCEDURE
subprog_body_2: t_PROCEDURE t_Identifier
subprog_body_2: t_FUNCTION t_Identifier
subprog_body_2: t_FUNCTION t_STRING

subprog_body_1:  /* empty */ { $$=""; }
//subprog_body_1    :  subprogram_instantiation_decl
subprog_body_1: subprog_body_1 subprog_body_3  { $$=$1+$2; }

subprog_body_3: subprog_decltve_item  { $$=$1; }
                                                              
/*--------------------------------------------------
--  Interface Lists and Associaton Lists
----------------------------------------------------*/

interf_list:   t_LeftParen interf_element interf_list_1 t_RightParen   { $$=""; }
interf_list:   t_LeftParen error t_RightParen   { $$=""; }
interf_list_1:  /* empty */
interf_list_1: interf_list_1 interf_list_2
interf_list_2: t_Semicolon interf_element

interf_element: interface_package_decl
                  {
                    // adding generic :  [ package foo  is new bar]
                    if (parse_sec==GEN_SEC)
                    {
                       addVhdlType(current->name.data(),getParsedLine(t_PACKAGE),Entry::VARIABLE_SEC,VhdlDocGen::GENERIC,$1.data(),0);
                    }
                  }
interf_element: interface_subprogram_decl
                  {
                    if (parse_sec==GEN_SEC)
                    {
                      int a=getParsedLine(t_FUNCTION);
                      int b=getParsedLine(t_PROCEDURE);

                      if (a>b) b=a;

                      addVhdlType(current->name.data(),b,Entry::VARIABLE_SEC,VhdlDocGen::GENERIC,$1.data(),0);
                    }
                  }
interf_element: interf_element_1 t_Identifier
                  {
                    if (parse_sec==GEN_SEC)
                    {
                        addVhdlType($2,s_str.iLine,Entry::VARIABLE_SEC,currP,$1.data(),0);
                    }
                  }
interf_element: interf_element_1 idf_list t_Colon interf_element_2 subtype_indic interf_element_3 interf_element_4
                  {
                    $$=$2+":"+$4+$5+$6+$7;
                    if (currP!=VhdlDocGen::COMPONENT)
                    {
                      if (currP==VhdlDocGen::FUNCTION || currP==VhdlDocGen::PROCEDURE)
                      {
                        addProto($1.data(),$2.data(),$4.data(),$5.data(),$6.data(),$7.data());
                      }
                      else
                      {
                        QCString i=$5+$6+$7;
                        if (currP==VhdlDocGen::GENERIC)
                          addVhdlType($2,s_str.iLine,Entry::VARIABLE_SEC,currP,i.data(),$4.data());
                        else if(parse_sec != GEN_SEC)
                          addVhdlType($2,s_str.iLine,Entry::VARIABLE_SEC,currP,i.data(),$4.data());
                      }
                      //   fprintf(stderr,"\n\n <<port  %s  >>\n",$$.data());
                    } // if component
                  }
interf_element_4: /* empty :=*/   { $$=""; }
interf_element_4: t_VarAsgn expr  { $$=":="+$2; }
interf_element_3: /* empty */     { $$=""; }
interf_element_3: t_BUFFER        { $$="buffer"; }
interf_element_3: t_BUS           { $$="bus"; }
interf_element_2: /* empty */     { $$=""; }
interf_element_2: mode            { $$=$1; }
interf_element_1: /* empty */     { $$=""; }
interf_element_1: object_class    { $$=$1; }

mode: t_IN                        { $$="in"; }
mode: t_OUT                       { $$="out"; }
mode: t_INOUT                     { $$="inout"; }
mode: t_BUFFER                    { $$="buffer"; }
mode: t_LINKAGE                   { $$="link"; }

association_list:   t_LeftParen association_element association_list_1 t_RightParen  { $$="("+$2+")"; }
association_list_1:  /* empty */                           { $$=""; }
association_list_1: association_list_1 association_list_2  { $$=$1+" "+$2; }
association_list_2: t_Comma association_element            { $$=", "+$2; }
// VHDL '93 range_constraint ::= range range
gen_association_list : gen_assoc gen_assoc { $$=$1+$2;}
                                
gen_association_list : gen_assoc { $$=$1; }

gen_assoc: t_LeftParen gen_association_element gen_association_list_1 t_RightParen 
    {
      QCString str="("+$2+$3;
      str.append(")");
      $$=str;
    }

gen_association_list: t_LeftParen  error t_RightParen { $$=""; }
gen_association_list: t_LeftParen t_OPEN t_RightParen { $$=" ( open ) "; }

gen_association_list_1:  /* empty */  { $$=""; }
gen_association_list_1: gen_association_list_1   gen_association_list_2  { $$=$1+" "+$2; }
gen_association_list_2: t_Comma gen_association_element { $$=","+$2; }

association_element: formal_part t_Arrow actual_part { $$=$1+"=>"+$3; }
association_element: actual_part { $$=$1; }
association_element: t_Box       { $$="<>"; }
association_element: t_DEFAULT   { $$="default"; }

/* changed ;gen_association_element   : association_element  */
gen_association_element: expr            { $$=$1; }
gen_association_element: choice t_Arrow expr { $$=$1+"=>"+$3; }
gen_association_element: discrete_range1 {  $$=$1 ; }

formal_part: name  { $$=$1; }

actual_part: expr      { $$=$1; }
actual_part: t_OPEN    { $$="open"; }
actual_part: t_INERTIAL expr    { $$="inertial"; }

/*--------------------------------------------------
--  Names and Expressions
----------------------------------------------------*/

expr: and_relation  { $$=$1; }
expr: relation  { $$=$1; }

shift_op: t_SLL { $$="sll"; }
        | t_SRA    { $$="sra"; }
        | t_SLA    { $$="sla"; }
        | t_SRL    { $$="srl"; }
        | t_ROR    { $$="ror"; }
        | t_ROL   { $$="rol"; }
        ;
and_relation: relation shift_op relation { $$= $1+$2+$3; }
and_relation: relation t_AND    relation  { $$= $1+" and "+$3; }
and_relation: relation t_XOR    relation  { $$= $1+" xor "+$3; }
and_relation: relation t_OR     relation  { $$= $1+" or "+$3; }
and_relation: relation t_NOR    relation  { $$= $1+" nor "+$3; }
and_relation: relation t_XNOR   relation  { $$= $1+"xnor"+$3; }
and_relation: relation t_NAND   relation { $$= $1+"nand"+$3; }
and_relation: and_relation t_NAND relation { $$= $1+"nand"+$3; }
and_relation: and_relation t_NOR  relation{ $$= $1+"nor"+$3; }
and_relation: and_relation t_XNOR relation  { $$= $1+"nand"+$3; }
and_relation: and_relation t_AND  relation { $$= $1+" and "+$3; }
and_relation: and_relation t_OR   relation  { $$= $1+" or "+$3; }
and_relation: and_relation t_XOR  relation  { $$= $1+" xor "+$3; }

/* ;relation   : unary_operator primary   */

relation: t_QQ primary                         { $$=" ?? "+$2; }
relation: primary                              { $$=$1; }
relation: t_Plus primary  %prec MED_PRECEDENCE { $$="+"+$2; }
relation: t_Minus primary %prec MED_PRECEDENCE { $$="-"+$2; }
relation: t_ABS primary                        { $$="abs"+$2; }
relation: t_NOT primary                        { $$="not "+$2; }
relation: primary t_DoubleStar primary         { $$=$1+" ** "+$3; }
relation: t_Minus primary t_DoubleStar primary { $$=$2+" ** "+$4; }

/*   relation : relation binary_operator primary */

relation: relation t_MOD   relation       { $$=$1+" mod "+$3; }
relation: relation t_REM   relation       { $$=$1+" rem "+$3; }
relation: relation t_Ampersand relation   { $$=$1+" & "+$3; }
relation: relation t_Star  relation       { $$=$1+" * "+$3; }
relation: relation t_Plus  relation       { $$=$1+" + "+$3; }
relation: relation t_Minus relation       { $$=$1+" - "+$3; }
relation: relation t_LESym relation       { $$=$1+" <= "+$3; }
relation: relation t_GESym relation       { $$=$1+" >= "+$3; }
relation: relation t_LTSym relation       { $$=$1+" < "+$3; }
relation: relation t_GTSym relation       { $$=$1+" > "+$3; }
relation: relation t_EQSym relation       { $$=$1+" = "+$3; }
relation: relation t_NESym relation       { $$=$1+" != "+$3; }
relation: relation t_Slash relation       { $$=$1+" / "+$3; }
relation: relation t_QNEQU relation       { $$=$1+" ?/= "+$3; }
relation: relation t_QEQU  relation       { $$=$1+" ?= "+$3; }
relation: relation t_QL    relation       { $$=$1+" ?< "+$3; }
relation: relation t_QG    relation       { $$=$1+" ?> "+$3; }
relation: relation t_QLT   relation       { $$=$1+" ?<= "+$3; }
relation: relation t_QGT   relation       { $$=$1+" ?>= "+$3; }

simple_exp: t_Minus  term  { $$ = "-"+$2; }
          | t_Plus term    { $$ = "+"+$2; }
          | term           { $$ = $1; }
          | simple_exp
            adding_op term { $$ = $1+" "+$2+" "+$3; }

adding_op: t_Ampersand { $$ = "&"; }
         | t_Minus     { $$ = "-"; }
         | t_Plus      { $$ = "+"; }
         ;

term: factor { $$=$1; }
    | factor multiplying_operator factor { $$ = $1+" "+$2+" "+$3; }
    ;

multiplying_operator: t_Star  { $$ = "*";   }
                    | t_REM   { $$ = "rem"; }
                    | t_MOD   { $$ = "mod"; }
                    | t_Slash { $$ = "/";   }

factor: primary                        { $$=$1; }
      | t_ABS  primary                 { $$="abs "+$2; }
      | t_NOT  primary                 { $$="not  "+$2; }
      |  primary t_DoubleStar  primary { $$ = $1+" ** "+$3; }

primary: name                          { $$=$1; }
primary: literal                       { $$=$1; }
primary: aggregate                     { $$=$1; }
primary: qualified_expr                { $$=$1; }
primary: allocator                     { $$=""; }
primary: t_LeftParen expr t_RightParen { $$="("+$2+")"; }

name:  mark           { $$=$1; }
name:  name2          { $$=$1; }
name:  external_name  { $$=$1; }
name2: t_StringLit    { $$=$1; }
name2: attribute_name { $$=$1; }
name2: ifts_name      { $$=$1; }

mark: t_Identifier    { $$=$1; }
mark: sel_name        { $$=$1; }

sel_name: name t_Dot suffix   { $$=$1+"."+$3; }

suffix: designator     { $$=$1; }
suffix: t_CharacterLit { $$=$1; }
suffix: t_ALL          { $$="all"; }

ifts_name: mark  gen_association_list { $$=$1+" "+$2; }
ifts_name: name2 gen_association_list { $$=$1+" "+$2; }

sigma:  t_Apostrophe { $$="'"; }
//sigma :  t_LEFTBR signature1 t_RIGHTBR  t_Apostrophe { $$="("+$2;;$$.append(")");$$.append("'"); }

attribute_name: mark  sigma t_Identifier   { $$=$1+"' "+$3; }
attribute_name: attribute_name t_LeftParen expr t_RightParen
attribute_name: name2 sigma t_Identifier   { $$=$1+" '"+$3; }
attribute_name: mark  sigma t_RANGE        { $$=$1+"' range "; }
attribute_name: name2 sigma t_RANGE        { $$=$1+"' range "; }

aggregate  : element_association_list2 t_RightParen  { $$=$1+" ) "; }
aggregate  : t_LeftParen choices t_Arrow expr t_RightParen  { $$="( "+$2+ "=>"+$4+" ) "; }

element_association_list2 : t_LeftParen element_association t_Comma element_association  { $$=" ( "+$2+","+$4; }
element_association_list2 : element_association_list2 t_Comma element_association   { $$=$1+","+$3; }

qualified_expr : mark t_Apostrophe t_LeftParen expr  t_RightParen { $$=$1+"'("+$4+" ) "; }
qualified_expr : mark t_Apostrophe aggregate  { $$=$1+"'"+$3; }

allocator: t_NEW mark mark allocator_1
allocator: t_NEW mark allocator_2
allocator: t_NEW qualified_expr
allocator_2:  /* empty */
allocator_2: gen_association_list
allocator_1:  /* empty */
allocator_1: gen_association_list


/*--------------------------------------------------
--  Element Association and Choices
----------------------------------------------------*/

element_association: choices t_Arrow expr { $$=$1+"=> "+$3; }
element_association: expr                 { $$=$1; }

choices: choice choices_1      { $$=$1+" "+$2; }
choices_1:  /* empty */        { $$="";        }
choices_1: choices_1 choices_2 { $$=$1+" "+$2; }
choices_2: t_Bar choice        { $$=" | "+$2;  }

choice: expr                   { $$=$1; }
choice: discrete_range1        { $$=$1; }
choice: t_OTHERS               { $$="others"; }

/*--------------------------------------------------
--	Type Declarations
----------------------------------------------------*/
type_decl: t_TYPE t_Identifier error t_Semicolon  { $$=""; }
type_decl: t_TYPE t_Identifier type_decl_1 t_Semicolon
           {
             addVhdlType($2,getParsedLine(t_TYPE),Entry::VARIABLE_SEC,VhdlDocGen::TYPE,0,$3.data());
            $$="type ";
            $$+=$2+$3+";";
           }
type_decl: t_TYPE error t_Semicolon { $$=""; }

type_decl_1:  /* empty */           { $$=""; }
type_decl_1: t_IS type_definition   { $$="  "+$2; }

type_definition: enumeration_type_definition    { $$=$1; }
type_definition: range_constraint               { $$=$1; }
type_definition: physical_type_definition       { $$=$1; }
type_definition: unconstrained_array_definition { $$=$1; }
type_definition: constrained_array_definition   { $$=$1; }
type_definition: record_type_definition         { $$=$1; }
type_definition: access_type_definition         { $$=$1; }
type_definition: file_type_definition           { $$=$1; }
type_definition: protected_type_declaration     { $$=$1; }
type_definition: protected_type_body            { $$=$1; }


enumeration_type_definition:   t_LeftParen enumeration_literal enumeration_type_definition_1 t_RightParen { $$="( "+$2+" "+$3+" )"; }
enumeration_type_definition_1: { $$=""; }
enumeration_type_definition_1: enumeration_type_definition_1 enumeration_type_definition_2 { $$=$1+" "+$2; }
enumeration_type_definition_2: t_Comma enumeration_literal { $$=","+$2; }

physical_type_definition : range_constraint  t_UNITS base_unit_decl
                           physical_type_definition_1 t_END unit_stat
                           {
                             $$=$1;
                             current->args=$3+"#"+$4;
                             current->args.prepend("units");
                             current->spec=VhdlDocGen::UNITS;
                           }

unit_stat: t_UNITS t_Identifier
unit_stat: t_UNITS

physical_type_definition_1: /* empty */ { $$=""; }
physical_type_definition_1: physical_type_definition_1 physical_type_definition_2 { $$=$1+" "+$2; }
physical_type_definition_2: secondary_unit_decl  { $$=$1+"#"; }

base_unit_decl: t_Identifier t_Semicolon { $$=$1; }

secondary_unit_decl: t_Identifier t_EQSym physical_literal t_Semicolon { $$=$1+"="+$3; }

unconstrained_array_definition: t_ARRAY t_LeftParen
                                index_subtype_definition unconstrained_array_definition_1 t_RightParen t_OF
                                subtype_indic
    {
      QCString sr1=" array ( "+$3+" "+$4;
      QCString sr2=" ) of "+$7;
      $$=sr1+sr2;
    }

unconstrained_array_definition_1: { $$=""; }
unconstrained_array_definition_1: unconstrained_array_definition_1 unconstrained_array_definition_2 { $$=$1+"  "+$2; }
unconstrained_array_definition_2: t_Comma index_subtype_definition { $$=", "+$2; }

index_subtype_definition: mark t_RANGE t_Box { $$=$1+" range<> "; }

constrained_array_definition: t_ARRAY index_constraint t_OF subtype_indic { $$=" array "+$2+" of "+$4; }

record_type_simple_name:/*empty*/     { $$=""; }
                       | t_Identifier { $$=$1; }

record_type_definition: t_RECORD element_decl record_type_definition_1 t_END
                        t_RECORD record_type_simple_name
    {
      QRegExp reg("[\\s]");
      QCString oo=$2+" "+$3;
      current->spec=VhdlDocGen::RECORD;
      current->args=oo;
      current->args.replace(reg,"%");
      current->args.prepend("record");
      $$=$2+" "+$3;
    }

record_type_definition_1: /*empty*/ { $$=""; }
record_type_definition_1: record_type_definition_1 record_type_definition_2
    {
      $$=$1+" "+$2;
    }
record_type_definition_2: element_decl { $$=$1; }

element_decl: idf_list t_Colon subtype_indic t_Semicolon { $$=$1+":"+$3+"#"; }

access_type_definition: t_ACCESS subtype_indic { $$="access "+$2; }

file_type_definition: t_FILE t_OF mark  { $$="file of "+$3; }

/*--------------------------------------------------
--  Subtypes and Constraints
----------------------------------------------------*/

subtype_decl: t_SUBTYPE t_Identifier t_IS subtype_indic t_Semicolon
    {
      addVhdlType($2,getParsedLine(t_SUBTYPE),Entry::VARIABLE_SEC,VhdlDocGen::SUBTYPE,0,$4.data());
    }
subtype_decl:     t_SUBTYPE error  t_Semicolon  { $$=""; }
subtype_indic:    mark subtype_indic_1          { $$=$1+" "+$2; }
subtype_indic:    subtype_indic1                { $$=$1; }
subtype_indic_1:  /* empty */                   { $$=""; }
subtype_indic_1:  gen_association_list          { $$=$1; }

subtype_indic1:   mark mark range_constraint    { $$=$1+" "+$2+" "+$3; }
subtype_indic1:   mark range_constraint         { $$=$1+" "+$2; }
subtype_indic1:   mark mark subtype_indic1_1    { $$=$1+" "+$2+" "+$3; }
subtype_indic1_1:  /* empty */                  { $$=""; }
subtype_indic1_1: gen_association_list          { $$=$1; }

range_constraint: t_RANGE range_spec            { $$="range "+$2; }
//range_constraint        : array_constraint

index_constraint: t_LeftParen discrete_range
                  index_constraint_1
                  t_RightParen                  { $$="("+$2+" "+$3+")"; }
index_constraint_1:  /* empty */                { $$=""; }
index_constraint_1: index_constraint_1
                    index_constraint_2          { $$=$1+" "+$2; }
index_constraint_2: t_Comma discrete_range      { $$=","+$2; }

discrete_range: subtype_indic                   { $$=$1; }
discrete_range: range_spec                      { $$=$1; }

discrete_range1 : subtype_indic1                { $$=$1; }
discrete_range1 : expr direction expr           { $$=$1+"  "+$2+"  "+$3; }

range_spec  : attribute_name                    { $$=$1; }
range_spec  : simple_exp direction simple_exp   { $$=$1+"  "+$2+"  "+$3; }

direction  : t_TO     { $$=" to "; }
direction  : t_DOWNTO { $$=" downto "; }

/*--------------------------------------------------
--  Objects, Aliases, Files, Disconnections
----------------------------------------------------*/

constant_decl: t_CONSTANT idf_list t_Colon subtype_indic constant_decl_1 t_Semicolon
                                  {
                                    QCString it=$4+" "+$5;
                                    //  fprintf(stderr,"\n currP %d \n",currP);
                                    addVhdlType($2,getParsedLine(t_CONSTANT),Entry::VARIABLE_SEC,VhdlDocGen::CONSTANT,0,it.data());
                                    $$="constant "+$2;
                                    $$+=": ";
                                    $$+=it+";";
                                  }
constant_decl_1:  /* empty */     { $$="";      }
constant_decl_1: t_VarAsgn expr   { $$=":="+$2; }

signal_decl: t_SIGNAL idf_list t_Colon subtype_indic signal_decl_1 signal_decl_2 t_Semicolon
                                  {
                                    QCString s=$4+" "+$6;
                                    addVhdlType($2,getParsedLine(t_SIGNAL),Entry::VARIABLE_SEC,VhdlDocGen::SIGNAL,0,s.data());
                                  }
signal_decl_2:  /* empty */       { $$=""; }
signal_decl_2: t_VarAsgn expr     { $$=":="+$2; }
signal_decl_1:  /* empty */       { $$=""; }
signal_decl_1: signal_kind        { $$=$1; }

variable_decl: t_VARIABLE idf_list t_Colon subtype_indic variable_decl_1 t_Semicolon
                                  {
                                    $$=$2+":"+$4+" "+$5+";";
                                    $$.prepend("variable: ");
                                  }
variable_decl: t_SHARED t_VARIABLE idf_list t_Colon subtype_indic variable_decl_1 t_Semicolon
                                  {
                                    $$=$5+" "+$6;
                                    addVhdlType($3,getParsedLine(t_VARIABLE),Entry::VARIABLE_SEC,VhdlDocGen::SHAREDVARIABLE,0,$$.data());
                                  }
variable_decl_1:  /* empty */     { $$=""; }
variable_decl_1: t_VarAsgn expr   { $$=":="+$2; }

object_class: t_CONSTANT          { $$="constant"; }
object_class: t_SIGNAL            { $$="signal"; }
object_class: t_VARIABLE          { $$="variable"; }
object_class: t_SHARED t_VARIABLE { $$="shared"; }
object_class: t_FILE              { $$="file"; }
object_class: t_TYPE              { $$="type"; }

signal_kind: t_BUS                { $$="bus"; }
signal_kind: t_REGISTER           { $$="register"; }

alias_decl: t_ALIAS alias_name_stat alias_spec t_IS name signature t_Semicolon
                                  {
                                    QCString s=$3+" is "+$5+$6;
                                    addVhdlType($2,getParsedLine(t_ALIAS),Entry::VARIABLE_SEC,VhdlDocGen::ALIAS,0,s.data());
                                   $$="alias "+$2;
                                   $$+=": ";
                                   $$+=s+";";
                                  }
alias_decl: t_ALIAS alias_name_stat alias_spec t_IS error t_Semicolon { $$=""; }

alias_name_stat: t_Identifier     { $$=$1; }
alias_name_stat: t_StringLit      { $$=$1; }

alias_spec :/*empty*/              { $$=""; }
           | t_Colon subtype_indic { $$=$2; }
           ;

file_decl: t_FILE idf_list t_Colon subtype_indic t_IS file_decl_1 expr t_Semicolon
           {
             addVhdlType($2,getParsedLine(t_FILE),Entry::VARIABLE_SEC,VhdlDocGen::VFILE,0,$4.data());
           }

file_decl: t_FILE idf_list t_Colon t_Identifier fi_dec t_Semicolon
           {
             QCString s=$4+" "+$5;
             addVhdlType($2,getParsedLine(t_FILE),Entry::VARIABLE_SEC,VhdlDocGen::VFILE,0,s.data());
           }

fi_dec: /*empty*/              { $$=""; }
      |  t_OPEN expr t_IS expr { $$="open "+$2+" is "+s_str.qstr; }


file_decl_1:  /* empty */   { $$=""; }
file_decl_1: mode           { $$=$1; }

disconnection_spec: t_DISCONNECT signal_list t_Colon mark t_AFTER expr t_Semicolon
                                      { $$="disconnect "+$2+":"+$4+" after "+$6; }
                                      
signal_list:   name signal_list_1 { $$=$1+$2; }
signal_list:   t_OTHERS   { $$="others"; }
signal_list:   t_ALL             { $$="all"; }
signal_list_1:  /* empty */  { $$=""; }
signal_list_1: signal_list_1 signal_list_2    { $$=$1+$2; }
signal_list_2: t_Comma name { $$=" , "+$2; }

/*--------------------------------------------------
--  Attribute Declarations and Specifications
----------------------------------------------------*/

attribute_decl: t_ATTRIBUTE t_Identifier t_Colon mark t_Semicolon
                {
                  addVhdlType($2,getParsedLine(t_ATTRIBUTE),Entry::VARIABLE_SEC,VhdlDocGen::ATTRIBUTE,0,$4.data());
                 $$= "attribute "+$2+ " : "+$4;
                }

attribute_spec: t_ATTRIBUTE t_Identifier t_OF entity_spec t_IS expr t_Semicolon
                {
                  QCString att=$4+" is "+$6;
                  addVhdlType($2,getParsedLine(t_ATTRIBUTE),Entry::VARIABLE_SEC,VhdlDocGen::ATTRIBUTE,0,att.data());
                  $$="attribute "+att+";";
                }

entity_spec : entity_name_list signature  t_Colon entity_class { $$=$1+$2+":"+$4; }	

entity_name_list:   designator entity_name_list_1         { $$=$1+" "+$2; }
entity_name_list:   t_OTHERS                              { $$="others";  }
entity_name_list:   t_ALL                                 { $$="all";     }
entity_name_list_1: /* empty */                           { $$="";        }
entity_name_list_1: entity_name_list_1 entity_name_list_2 { $$=$1+" "+$2; }
entity_name_list_2: t_Comma designator                    { $$=","+$2;    }

entity_class: t_ENTITY        { $$="entity";        }
entity_class: t_ARCHITECTURE  { $$="architecture";  }
entity_class: t_PACKAGE       { $$="package";       }
entity_class: t_CONFIGURATION { $$="configuration"; }
entity_class: t_COMPONENT     { $$="component";     }
entity_class: t_LABEL         { $$="label";         }
entity_class: t_TYPE          { $$="type";          }
entity_class: t_SUBTYPE       { $$="subtype";       }
entity_class: t_PROCEDURE     { $$="procedure";     }
entity_class: t_FUNCTION      { $$="function";              }
entity_class: t_SIGNAL        { $$="signal";        }
entity_class: t_VARIABLE      { $$="variable";      }
entity_class: t_CONSTANT      { $$="constant";      }
entity_class: t_GROUP         { $$="group";         }
entity_class: t_FILE          { $$="file";          }
entity_class: t_UNITS         { $$="units";         }
entity_class: t_LITERAL       { $$="literal";       }
entity_class: t_SEQUENCE      { $$="sequence";      }
entity_class: t_PROPERTY      { $$="property";      }


/*--------------------------------------------------
--  Schemes
--------------------------------------------------------------------------*/

if_generation_scheme: if_scheme { $$=$1; }

if_scheme: t_IF expr t_GENERATE  generate_statement_body  if_scheme_1 if_scheme_2 { $$=""; }
if_scheme: t_IF lable expr t_GENERATE  generate_statement_body  if_scheme_1 if_scheme_2 { $$=""; }

if_scheme_2: /* empty */ { $$=""; }
if_scheme_2: t_ELSE t_GENERATE  generate_statement_body { $$="else generate "+$3; }
if_scheme_2: t_ELSE lable t_GENERATE  generate_statement_body { $$="else "+$2+" generate "+$4; }
if_scheme_1: /* empty */  { $$=""; }
if_scheme_1: if_scheme_1 if_scheme_3  { $$=$1+$2; }
if_scheme_3: t_ELSIF expr t_GENERATE generate_statement_body { $$="elsif "+$2+" generate "+$4; }
if_scheme_3: t_ELSIF lable expr t_GENERATE generate_statement_body  { $$="elsif "+$2+$3+" generate "+$5; }

generation_scheme: for_scheme { $$=$1; }

iteration_scheme: for_scheme     { $$=$1; }
iteration_scheme: while_scheme { $$=$1; }

for_scheme: t_FOR t_Identifier t_IN discrete_range 
  {
    if (!lab.isEmpty())
    {
      $$=lab+" :for "+$2+" in "+$4;
    }
    else
    {
      $$=" for "+$2+" in "+$4;
    }
    FlowChart::addFlowChart(FlowChart::FOR_NO,0,$$,lab.data());
    lab.resize(0);
  }
for_scheme: t_FOR lable t_Identifier t_IN discrete_range 
  {
    $$=lab+" for "+$2+$3+" in "+$5;
    FlowChart::addFlowChart(FlowChart::FOR_NO,0,$$,lab.data());
    lab="";
  }

while_scheme: t_WHILE expr {
                             $$=" while "+$2;
                             FlowChart::addFlowChart(FlowChart::WHILE_NO,0,$$,lab.data());
                             lab="";
                           }

/*--------------------------------------------------
--  Concurrent Statements
----------------------------------------------------*/

concurrent_stats:   concurrent_stats_1      { $$=$1; }
concurrent_stats_1: /* empty */             { $$=""; }
concurrent_stats_1: concurrent_stats_1 concurrent_stats_2 { $$=$1+$2; }
concurrent_stats_2: concurrent_stat         { $$=$1; }

concurrent_stat : block_stat                { $$=$1; }
                | concurrent_assertion_stat { $$=$1; }
                | concurrent_procedure_call { $$=$1; }
                | concurrent_signal_assign_stat { $$=$1; }
                | comp_inst_stat            {
                                              QCString li=$1;
                                              $$=$1;
                                            }
                | generate_stat             { $$=$1; }
                | procs_stat                   

block_stat: t_Identifier t_Colon t_BLOCK { pushLabel(genLabels,$1); } block_stat_0 block_stat_1 block_stat_2
            block_stat_3 block_stat_4 t_BEGIN concurrent_stats t_END t_BLOCK block_stat_5
            t_Semicolon 
            {
              $$=$1+":block"; //+$4+$5+$6+$7+$8+"begin "+$10+" block "+$13;
              genLabels=popLabel(genLabels);
            }
block_stat_5: /* empty */  { $$=""; }
block_stat_5: t_Identifier { $$=$1; }
block_stat_4: /* empty */  { $$=""; }
block_stat_4: block_stat_4 block_stat_6 { $$=$1+$2; }
block_stat_6: block_decltve_item { $$=$1; }
block_stat_3: /* empty */  { $$=""; }
block_stat_3: t_PORT interf_list t_Semicolon block_stat_7   { $$="port "+$2+";"+$4; }
//block_sta_7:  /* empty */ { $$=""; }
block_stat_7: t_PORT t_MAP association_list t_Semicolon     { $$="port map "+$3; }
block_stat_2: /* empty */  { $$=""; }
block_stat_2: t_GENERIC interf_list t_Semicolon block_stat_8 { $$="generic "+$2+";"+$4; }
block_stat_8: /* empty */  { $$=""; }
block_stat_8: t_GENERIC t_MAP association_list t_Semicolon  { $$="generic map "+$3; }
block_stat_1: /* empty */  { $$=""; }
block_stat_1: t_LeftParen expr t_RightParen  block_stat_0  { $$="("+$2+")"+$4; }
block_stat_0: /* empty */  { $$=""; }
block_stat_0: t_IS  { $$=" is "; }

dot_name: t_Identifier                 { $$=$1; }
        | dot_name  t_Dot t_Identifier { $$=$1+"."+$3; }
        ;

mark_comp: dot_name  comp_1      { $$=$1+" "+$2; }
mark_comp: dot_name              { $$=$1; }

comp_1: t_LeftParen t_Identifier  t_RightParen  { $$="("+$2+")"; }

vcomp_stat: t_CONFIGURATION      { $$="configuration";yyLineNr=s_str.iLine; }
vcomp_stat: t_ENTITY             { $$="entity";yyLineNr=s_str.iLine; }
vcomp_stat: t_COMPONENT          { $$="component";yyLineNr=s_str.iLine; }

comp_inst_stat: t_Identifier t_Colon name { yyLineNr=s_str.iLine; }     t_GENERIC t_MAP association_list comp_inst_stat_1 t_Semicolon
                               {
                                 addCompInst($1.lower().data(),$3.lower().data(),0,yyLineNr);$$="";
                               }
comp_inst_stat: t_Identifier t_Colon name { yyLineNr=s_str.iLine; }    t_PORT t_MAP association_list t_Semicolon
                               {
                                 addCompInst($1.lower().data(),$3.lower().data(),0,yyLineNr);$$="222";
                               }

comp_inst_stat: t_Identifier t_Colon vcomp_stat  mark_comp t_PORT t_MAP association_list t_Semicolon
                               {
                                 addCompInst($1.lower().data(),$4.lower().data(),$3.data(),yyLineNr);$$="";
                               }
comp_inst_stat: t_Identifier t_Colon vcomp_stat mark_comp t_GENERIC t_MAP association_list comp_inst_stat_1 t_Semicolon
                               {
                                 addCompInst($1.lower().data(),$4.lower().data(),$3.lower().data(),yyLineNr);$$="";
                               }
comp_inst_stat_1:  /* empty                                       { $$=""; } */  
comp_inst_stat_1: t_PORT t_MAP association_list //    { $$="port map"+$3; }

concurrent_assertion_stat:  t_Identifier t_Colon  assertion_stat  { $$=$1+":"+$3; }
concurrent_assertion_stat:  assertion_stat              { $$=$1; }

concurrent_assertion_stat:  t_Identifier t_Colon  t_POSTPONED  assertion_stat { $$=$1+":"+"postponed "+$4; }
concurrent_assertion_stat:   t_POSTPONED assertion_stat { $$="postponed "+$2; }

concurrent_procedure_call: t_Identifier t_Colon procedure_call_stat { $$=$1+":"+$3; }
concurrent_procedure_call: procedure_call_stat { $$=$1; }

concurrent_procedure_call: t_Identifier t_Colon t_POSTPONED procedure_call_stat { $$=$1+":"+"postponed "+$4; }
concurrent_procedure_call: t_POSTPONED procedure_call_stat { $$="postponed "+$2; }

concurrent_signal_assign_stat: t_Identifier t_Colon condal_signal_assign { $$=$1+":"+$3; }
concurrent_signal_assign_stat: condal_signal_assign  { $$=$1; }

concurrent_signal_assign_stat: t_Identifier t_Colon  t_POSTPONED  condal_signal_assign { $$=$1+":"+"postponed "+$4; }
concurrent_signal_assign_stat: t_POSTPONED  condal_signal_assign { $$="postponed "+$2; }

concurrent_signal_assign_stat: t_Identifier t_Colon t_POSTPONED sel_signal_assign { $$=$1+":"+"postponed "+$4; }
concurrent_signal_assign_stat: t_POSTPONED sel_signal_assign { $$="postponed "+$2; }

concurrent_signal_assign_stat: t_Identifier t_Colon sel_signal_assign  { $$=$1+":"+$3; }
concurrent_signal_assign_stat: sel_signal_assign  { $$=$1; }

condal_signal_assign: target t_LESym opts   condal_wavefrms t_Semicolon { $$=$1+"<="+$3+$4; }

condal_wavefrms: wavefrm { $$=$1; }
condal_wavefrms: wavefrm t_WHEN expr  { $$=$1+" when "+$3; }
condal_wavefrms: wavefrm t_WHEN expr t_ELSE condal_wavefrms { $$=$1+" when "+$3+"else"+$5; }

wavefrm:   wavefrm_element wavefrm_1 { $$=$1+$2; }
wavefrm:   t_UNAFFECTED { $$="unaffected"; }
wavefrm_1: /* empty */  { $$=""; }
wavefrm_1: wavefrm_1 wavefrm_2 { $$=$1+$2; }
wavefrm_2: t_Comma wavefrm_element { $$=","+$2; }

wavefrm_element:   expr wavefrm_element_1 { $$=$1+$2; }
wavefrm_element_1: /* empty */ { $$=""; }
wavefrm_element_1: t_AFTER expr { $$="after "+$2; }
wavefrm_element_1: t_NULL wavefrm_element_2 { $$=" null "+$2; }
wavefrm_element_1: t_NULL { $$=" null "; }
wavefrm_element_2: t_AFTER expr { $$="after "+$2; }

target: name { $$=$1; }
target: aggregate   { $$=$1; }

opts: opts_1 opts_2   { $$=$1+$2; }

opts_2: /* empty */  { $$=""; }
opts_2: t_TRANSPORT  { $$="transport "; }
opts_2: t_REJECT expr t_INERTIAL  { $$="transport"+$2+" intertial "; }
opts_2: t_INERTIAL  { $$=" intertial "; }

opts_1: /* empty */ { $$=""; }
opts_1: t_GUARDED { $$=" guarded "; }

sel_signal_assign: t_WITH expr t_SELECT target t_LESym opts sel_wavefrms t_Semicolon 
 { $$="with "+$2+" select "+$4+"<="+$6+$7; }
 
sel_wavefrms:   sel_wavefrms_1 wavefrm t_WHEN choices  { $$=$1+$2; }
sel_wavefrms_1: /* empty */  { $$=""; }
sel_wavefrms_1: sel_wavefrms_1 sel_wavefrms_2 { $$=$1+$2; }
sel_wavefrms_2: wavefrm t_WHEN choices t_Comma { $$=$1+" when "+$3; }

gen_stat1: /* empty */  { $$=""; }
        |  block_declarative_part  t_BEGIN { $$=$1+" begin "; }
        | t_BEGIN { $$="begin "; }

 // problem with double end
 // end;
 // end generate;

generate_statement_body:  gen_stat1 concurrent_stats

generate_stat : t_Identifier  t_Colon
                { pushLabel(genLabels,$1); }
                generation_scheme t_GENERATE
                gen_stat1 concurrent_stats  opstat

// stems from VHDL 2008 generate_statement_body
opstat: end_stats t_END generate_stat_1 t_Semicolon { genLabels=popLabel(genLabels); }
opstat: t_END generate_stat_1 t_Semicolon           {genLabels=popLabel(genLabels); }

generate_stat: t_Identifier  t_Colon
               { pushLabel(genLabels,$1); }
               if_generation_scheme opstat //    t_END   generate_stat_1 t_Semicolon { genLabels=popLabel(genLabels); }
generate_stat: t_Identifier  t_Colon case_scheme

generate_stat_1: t_GENERATE              { $$=""; }
generate_stat_1: t_GENERATE t_Identifier { $$=$2; }

//end_stats :
end_stats: t_END t_Semicolon   { $$="end"; }
end_stats: t_END t_Identifier t_Semicolon   { $$="end "+$2; }

procs_stat: t_Identifier t_Colon procs_stat1
         {  
                 current->name=$1;
                 tempEntry=current;
                 current->endBodyLine=s_str.yyLineNr;
                 newEntry();
                 currName=$1;
               }

procs_stat: procs_stat1
               {
                 current->name=VhdlDocGen::getProcessNumber();
                 current->endBodyLine=s_str.yyLineNr;
                 tempEntry=current;
                 newEntry();
               }

procs_stat1: procs_stat1_5
               {  
               currP=VhdlDocGen::PROCESS; 
               current->startLine=s_str.yyLineNr;
               current->bodyLine=s_str.yyLineNr;
               }
               t_PROCESS procs_stat1_1 procs_stat1_2
               {
                 if ($5.data())
                  FlowChart::addFlowChart(FlowChart::VARIABLE_NO,$5.data(),0);
                FlowChart::addFlowChart(FlowChart::BEGIN_NO,"BEGIN",0);
               }
               t_BEGIN seq_stats t_END

               procs_stat1_3 t_Semicolon
               { 
                $5.stripPrefix($4.data());
                tempEntry=current;
                currP=0;
                createFunction(currName,VhdlDocGen::PROCESS,$4.data());
                createFlow();
                currName="";
               }
procs_stat1: error t_END procs_stat1_3  t_Semicolon { currP=0; }

procs_stat1_3:  /* empty */
procs_stat1_3: procs_stat1_5  t_PROCESS  procs_stat1_6

procs_stat1_5:  /* empty */ { $$=""; }
procs_stat1_5: t_POSTPONED  { $$="postponed"; }

procs_stat1_6:  /* empty */ { $$=""; }
procs_stat1_6: t_Identifier { $$=$1; }

procs_stat1_2:  /* empty */  { $$=""; }
procs_stat1_2:  t_IS { $$=""; }   
procs_stat1_2: procs_stat1_2 procs_stat1_4   { $$+=$2; }
procs_stat1_4: procs_decltve_item           { $$=$1; }
procs_stat1_1:  /* empty */                                    { $$=""; }
procs_stat1_1: t_LeftParen t_ALL t_RightParen                  { $$="all"; }
procs_stat1_1: t_LeftParen sensitivity_list t_RightParen       { $$=$2; }

sensitivity_list:   name sensitivity_list_1                    { $$=$1+" "+$2; }
sensitivity_list_1: /* empty */                                { $$=""; }
sensitivity_list_1: sensitivity_list_1 sensitivity_list_2      { $$=$1+" "+$2; }
sensitivity_list_2: t_Comma name                               { $$=","+$2; }

/*--------------------------------------------------
--  Sequential Statements
----------------------------------------------------*/

seq_stats: seq_stats_1               { $$=$1; }
seq_stats_1: /* empty */             { $$=""; }
seq_stats_1: seq_stats_1 seq_stats_2 { $$=$1+$2; }
seq_stats_2: seq_stat                { $$=$1; }
seq_stat: assertion_stat             { $$=$1;    FlowChart::addFlowChart(FlowChart::TEXT_NO,$$.data(),0); }
seq_stat: lable assertion_stat       { $$=$1+$2; FlowChart::addFlowChart(FlowChart::TEXT_NO,$$.data(),0); }
seq_stat: case_stat                  { $$=$1; }
seq_stat: exit_stat                  { $$=$1; }
seq_stat: if_stat                    { $$=""; } 
seq_stat: loop_stat                  { $$=$1; }
seq_stat: next_stat                  { $$=$1; }
seq_stat: null_stat                  { $$=$1; FlowChart::addFlowChart(FlowChart::TEXT_NO,$$.data(),0); }
seq_stat: procedure_call_stat        { $$=$1; FlowChart::addFlowChart(FlowChart::TEXT_NO,$$.data(),0); } 
seq_stat: return_stat                { $$=$1; FlowChart::addFlowChart(FlowChart::RETURN_NO,$$.data(),0); }
seq_stat: lable signal_assign_stat   { $$=$1+$2; }
seq_stat: signal_assign_stat         { $$=$1; FlowChart::addFlowChart(FlowChart::TEXT_NO,$$.data(),0); }
seq_stat: variable_assign_stat       { $$=$1; FlowChart::addFlowChart(FlowChart::TEXT_NO,$$.data(),0); }
seq_stat: wait_stat                  { $$=$1; FlowChart::addFlowChart(FlowChart::TEXT_NO,$$.data(),0); }
seq_stat: lable wait_stat            { $$=$1+$2; FlowChart::addFlowChart(FlowChart::TEXT_NO,$$.data(),0); }
seq_stat: report_statement           { $$=$1; FlowChart::addFlowChart(FlowChart::TEXT_NO,$$.data(),0); }

report_statement: loop_stat_1 t_REPORT expr assertion_stat_2  t_Semicolon { $$=$1+"report "+$3+$4+";";  }

assertion_stat: t_ASSERT expr assertion_stat_1 assertion_stat_2 t_Semicolon  { $$="assert "+$2+$3+$4+";"; }
assertion_stat_2:  /* empty */                    { $$=""; }
assertion_stat_2     : t_SEVERITY expr  { $$=" serverity "+$2; } 
assertion_stat_1     :  /* empty */            { $$=""; }
assertion_stat_1     : t_REPORT expr  { $$=" report "+$2; }

choice_stat :  /* empty */ { $$=""; }
choice_stat :  t_Q            { $$="?"; }

choice_stat_1:  /* empty */   { $$=""; }
choice_stat_1 :                  t_Q     { $$="?"; }
choice_stat_1 : t_Identifier  { $$=$1; }


case_stat  : t_CASE choice_stat expr 
                   {
                     QCString ca="case "+$2+$3;
                     FlowChart::addFlowChart(FlowChart::CASE_NO,0,ca);
                   }                 
                   t_IS case_stat_alternative case_stat_1 t_END t_CASE choice_stat_1  t_Semicolon
                   { 
                     FlowChart::moveToPrevLevel();
                     FlowChart::addFlowChart(FlowChart::END_CASE,"end case",0);
                   }
          

case_stat  : lable t_CASE choice_stat expr
                   {
                     QCString ca="case "+$3+$4;
                     FlowChart::addFlowChart(FlowChart::CASE_NO,0,ca);
                   } 
                   t_IS case_stat_alternative case_stat_1 t_END t_CASE choice_stat_1  t_Semicolon
                   {
                     FlowChart::moveToPrevLevel();
             
                     FlowChart::addFlowChart(FlowChart::END_CASE,0,0);
                   }

case_stat       : t_CASE error t_END t_CASE choice_stat_1  t_Semicolon  { $$=""; }
case_stat_1     :  /* empty */             { $$=""; }
case_stat_1     : case_stat_1 case_stat_2  { $$=$1+$2; }
case_stat_2     : case_stat_alternative    { $$=$1; }
case_stat_alternative     : t_WHEN choices t_Arrow
  { 
    QCString t="when ";
    t+=$2+"=> ";
    FlowChart::addFlowChart(FlowChart::WHEN_NO,$2.data(),t);
  }
  seq_stats { $$=""; FlowChart::moveToPrevLevel(); }

if_stat: t_IF expr t_THEN
  {
    $2.prepend("if ");
    FlowChart::addFlowChart(FlowChart::IF_NO,0,$2);
  }  
  seq_stats   
 
  if_stat_1 if_stat_2 t_END t_IF t_Semicolon 
  {
    FlowChart::moveToPrevLevel();
    FlowChart::addFlowChart(FlowChart::ENDIF_NO,0,0);
  } 
     
if_stat_2  :  /* empty */             { $$=""; }
if_stat_2  : t_ELSE    
  {
    FlowChart::addFlowChart(FlowChart::ELSE_NO,0,0);
  } 
  seq_stats   { $$=""; }

 
 

if_stat_1  :  /* empty */             { $$=""; }
if_stat_1  : if_stat_1 if_stat_3      { $$=$1+$2; }
if_stat_3  : t_ELSIF expr t_THEN 
  { 
    $2.prepend("elsif ");
    FlowChart::addFlowChart(FlowChart::ELSIF_NO,0,$2.data());
  } seq_stats { $$=""; }
  
loop_stat:   loop_stat_1 loop_stat_2 t_LOOP seq_stats t_END t_LOOP loop_stat_3 t_Semicolon
  {
    $$=$1+$2+" loop "+$4+" end loop" +$7;
    QCString endLoop="end loop" + $7;
    FlowChart::moveToPrevLevel();
    FlowChart::addFlowChart(FlowChart::END_LOOP,endLoop.data(),0);
  }

loop_stat_3: /* empty */ { $$=""; }
loop_stat_3: t_Identifier { $$=$1; }
loop_stat_2: /* empty */ { $$=""; 
                           FlowChart::addFlowChart(FlowChart::LOOP_NO,0,"infinite loop");
                         }
loop_stat_2: iteration_scheme
loop_stat_1: /* empty */ { $$=""; }
loop_stat_1: t_Identifier t_Colon { $$=$1+":";lab=$1; }

exit_stat  : loop_stat_1 t_EXIT exit_stat_1 exit_stat_2 t_Semicolon   
                       {
                         FlowChart::addFlowChart(FlowChart::EXIT_NO,"exit",$4.data(),$3.data()); 
                         lab.resize(0);
                       }
exit_stat_2     :  /* empty */    { $$=""; }
exit_stat_2     : t_WHEN expr     { $$="when "+$2; }
exit_stat_1     :  /* empty */    { $$=""; }
exit_stat_1     : t_Identifier    { $$=$1;lab=$$; }


next_stat: loop_stat_1  t_NEXT next_stat_1 next_stat_2 t_Semicolon
                       {
                         FlowChart::addFlowChart(FlowChart::NEXT_NO,"next ",$4.data(),$3.data()); 
                         lab.resize(0);
                       }
                    
next_stat_2:  /* empty */      { $$=""; }
next_stat_2: t_WHEN expr { $$="when "+$2; }
next_stat_1:  /* empty */      { $$=""; }
next_stat_1: t_Identifier      { $$=$1;lab=$$; }

null_stat: t_NULL t_Semicolon { $$="null"; $$+=";"; }

procedure_call_stat: name t_Semicolon 
 {
   $$=$1+";"; 
 }

return_stat:   t_RETURN return_stat_1 t_Semicolon { $$="return "+$2+";"  ; }
return_stat_1: /* empty */  { $$=""; }
return_stat_1:   expr { $$=$1; }

signal_assign_stat: target t_LESym wavefrm t_Semicolon                   { $$=$1+" <="+$3+";"  ; }
                  | target t_LESym delay_mechanism wavefrm t_Semicolon   { $$=$1+ "<= "+$3+$4 +";"; }
                  | target t_LESym t_FORCE inout_stat  expr t_Semicolon  { $$=$1+ "<= "+ " force  "+$4+";" ; }
                  | target t_LESym t_RELEASE inout_stat t_Semicolon      { $$=$1+ "<= "+" release "+$4 +";"; }
                  | selected_signal_assignment                           { $$=$1; }
                  | conditional_signal_assignment                        { $$=$1; }
                  ;

variable_assign_stat: variable_assign_stat_1 t_Semicolon                 { $$=$1+";"; }
                    | conditional_variable_assignment                    { $$=$1; }
                    | lable selected_variable_assignment                 { $$=$1; }
                    | selected_variable_assignment                       { $$=$1; }

lable: t_Identifier t_Colon                                              { $$=$1+":"; }
variable_assign_stat_1: target t_VarAsgn expr                            { $$=$1+":="+$3; }
variable_assign_stat_1: lable target t_VarAsgn expr                      { $$=$1+$2+":="+$4; }

wait_stat:   t_WAIT wait_stat_1 wait_stat_2 wait_stat_3 t_Semicolon
                  {
                     $$="wait "+$2+$3+$4+";";
                  }

wait_stat_3: /* empty */            { $$=""; }
wait_stat_3: t_FOR expr             { $$="for "+$2; } 
wait_stat_2: /* empty */            { $$=""; }
wait_stat_2: t_UNTIL expr           { $$=" until "+$2; }
wait_stat_1: /* empty */            { $$=""; }
wait_stat_1: t_ON sensitivity_list  { $$=" on "+$2; }


/*--------------------------------------------------
--  Components and Configurations
----------------------------------------------------*/
comp_end_dec : t_END                              { lastEntity=0; lastCompound=0; genLabels.resize(0); }
             | t_END t_COMPONENT entity_decl_5
             | t_END t_ARCHITECTURE entity_decl_5 { lastCompound=0; genLabels.resize(0); }
             | t_END t_ENTITY entity_decl_5       { lastEntity=0;lastCompound=0; genLabels.resize(0); }
             | t_END t_Identifier                 { lastEntity=0; lastCompound=0; genLabels.resize(0); }

iss :/*empty*/ { currP=VhdlDocGen::COMPONENT; }
    |  t_IS    { currP=VhdlDocGen::COMPONENT; }

comp_decl: t_COMPONENT t_Identifier iss comp_decl_1 comp_decl_2 comp_end_dec  t_Semicolon
           {
             addVhdlType($2,getParsedLine(t_COMPONENT),Entry::VARIABLE_SEC,VhdlDocGen::COMPONENT,0,0);
             currP=0;
           }
comp_decl_2:  /* empty */                      { $$=""; }
comp_decl_2: t_PORT interf_list t_Semicolon    { $$=$2; }
comp_decl_1:  /* empty */                      { $$=""; }
comp_decl_1: t_GENERIC interf_list t_Semicolon { $$=$2; }

block_config: t_FOR block_spec block_config_1 block_config_2 { levelCounter--; }  t_END t_FOR t_Semicolon
          {
          }

block_config:   t_FOR error t_END t_FOR t_Semicolon { $$=""; }
block_config_2: /* empty */                         { $$=""; }
block_config_2: block_config_2 block_config_3       { $$=$1+"  "; }
block_config_3: config_item                         { $$=$1; }
block_config_1: /* empty */                         { $$=""; }
block_config_1: block_config_1 block_config_4       { $$=$1; }
block_config_4: use_clause                          { $$=$1; }

block_spec: name
    {
      $$=$1;
      if (levelCounter==0)
        addConfigureNode($1.data(),NULL,TRUE,FALSE);
      else
        addConfigureNode($1.data(),NULL,FALSE,FALSE);
        levelCounter++;
    }

config_item: block_config { $$=$1; }
config_item: comp_config  { $$=$1; }

comp_config: t_FOR comp_spec comp_config_1 comp_config_2 t_END t_FOR t_Semicolon
             {
               $$=$2+" "+$3+" "+$4;
             }
comp_config_2:  /* empty */   { $$=""; }
comp_config_2: block_config   { $$=$1; }
comp_config_1:  /*empty*/     { $$=""; }

comp_config_1: binding_indic_1  binding_indic_2  t_Semicolon  
{ 
  $$=""; 
}
comp_config_1: t_USE t_VUNIT idf_list  t_Semicolon             { $$=""; }
comp_config_1: t_USE binding_indic t_Semicolon
             {
               addConfigureNode(compSpec.data(),$2.data(),FALSE,TRUE);
             }

config_spec: t_FOR comp_spec comp_spec_stat t_Semicolon                         
             { 
               addConfigureNode($2.data(),$3.data(),TRUE,FALSE,TRUE);
             }
config_spec: t_FOR comp_spec comp_spec_stat t_Semicolon t_END t_FOR t_Semicolon 
             { 
               addConfigureNode($2.data(),$3.data(),TRUE,FALSE,TRUE);
              }

comp_spec_stat: t_USE  binding_indic               { 
                                                     $$=$2;
                                                   }
comp_spec_stat: t_USE t_VUNIT idf_list t_Semicolon 
{ 
  $$="";
}
comp_spec_stat: binding_indic_1  binding_indic_2   
                          { 
                          $$="";
                           }

comp_spec: inst_list t_Colon expr
             {
               $$=$1+":"+$3;
               compSpec=$$;
             }

inst_list: idf_list  { $$=$1; }
inst_list: t_ALL     { $$="all"; }
inst_list: t_OTHERS  { $$="others"; }

binding_indic   : entity_aspect binding_indic_1 binding_indic_2 { $$=$1; }

binding_indic_2: { $$=""; }
binding_indic_2: t_PORT t_MAP association_list  { $$="port map "+$3; }

binding_indic_1: { $$=""; }
binding_indic_1: t_GENERIC t_MAP association_list { $$="generic map "+$3; }


entity_aspect: t_ENTITY name { $$="entity "+$2; }
entity_aspect: t_CONFIGURATION mark { $$="configuration "+ $2; }
entity_aspect: t_OPEN { $$="open "; }
             ;

group_constituent: t_Identifier    { $$=$1; }
                 | t_CharacterLit { $$=$1; }
                 ;

group_constituent_list: group_constituent                                { $$=$1; }
                      | group_constituent_list t_Comma group_constituent { $$=$1+","+$3; }
                      ;

group_declaration : t_GROUP t_Identifier t_Colon group_name   t_LeftParen  group_constituent_list  t_RightParen t_Semicolon
                    {
                      // $$=$2+":"+$4+$6;
                      $$="("+$4+$6+")";
                      addVhdlType($2,getParsedLine(t_GROUP),Entry::VARIABLE_SEC,VhdlDocGen::GROUP,$$.data(),0);
                    }

group_template_declaration :  t_GROUP  t_Identifier t_IS  t_LeftParen  entity_class_entry_list  t_RightParen t_Semicolon
                    {
                      $$=$2+":"+$5;
                      addVhdlType($2,getParsedLine(t_GROUP),Entry::VARIABLE_SEC,VhdlDocGen::GROUP,$5.data(),0);
                    }

group_template_declaration: t_GROUP  t_Identifier t_IS  t_LeftParen error t_Semicolon  t_RightParen{ $$=""; }
 

entity_class_entry : entity_class tbox { $$=$1+$2; }

tbox :  /* empty */ { $$="";   }
tbox :  t_Box       { $$="<>"; }

entity_class_entry_list: entity_class_entry         { $$=$1; }
                       | entity_class_entry_list
                         t_Comma entity_class_entry { $$=$1+","+$3; }
                       ;

group_name: t_Identifier { $$=$1; }
group_name: t_StringLit  { $$=$1; }

t_Identifier: t_LETTER
    {
      $$=s_str.qstr;
    }

t_BitStringLit: t_DIGIT
    {
      $$=s_str.qstr;
    }

t_StringLit: t_STRING
    {
      $$=s_str.qstr;
    }

t_AbstractLit: t_ABSTRLIST
    {
      $$=s_str.qstr;
    }

t_CharacterLit: t_CHARLIST
    {
      $$=s_str.qstr;
    }


/*--------------------------------------------------
--  VHDL 2002 extensions
-- to do: must be added
-----------------------------------------------------*/
protected_type_declaration:t_PROTECTED protected_stats t_END protected_stat_1 { $$=""; }
protected_type_declaration:t_PROTECTED error  t_END protected_stat_1 { $$=""; }

protected_stats:       /* empty */
protected_stats:       protected_stats   protected_stat_decl_1
protected_stat_decl_1: protected_type_declaration_item
protected_stat_1:      t_PROTECTED
protected_stat_1:      t_PROTECTED t_Identifier

protected_type_declaration_item: use_clause
protected_type_declaration_item: attribute_spec
protected_type_declaration_item: subprog_decl
protected_type_declaration_item:  subprogram_instantiation_decl

protected_type_body: t_PROTECTED t_BODY protected_body_stats t_END protected_body_stat_1 { $$=""; }
protected_type_body: t_PROTECTED t_BODY error t_END protected_body_stat_1 { $$=""; }

protected_body_stats: /* empty */
protected_body_stats:  protected_body_stats   protected_body_stat_decl_1
protected_body_stat_decl_1: protected_type_body_declaration_item

protected_body_stat_1: t_PROTECTED t_BODY
protected_body_stat_1: t_PROTECTED t_BODY t_Identifier

protected_type_body_declaration_item: subprog_decltve_item // same as subprog

/*--------------------------------------------------
--  VHDL 2008 extensions
-- to do: must be added
-----------------------------------------------------*/
context_ref: t_CONTEXT  sel_list t_Semicolon { $$="context "+$2; }

context_decl: t_CONTEXT t_Identifier t_IS { parse_sec=CONTEXT_SEC; }  libustcont_stats t_END context_stat_1 t_Semicolon
                        {
                          parse_sec=0;
                          QCString v=$5;
                          addVhdlType($2,getParsedLine(t_LIBRARY),Entry::VARIABLE_SEC,VhdlDocGen::LIBRARY,"context",$5.data());
                        }
context_decl: t_CONTEXT t_Identifier t_IS  t_END context_stat_1 t_Semicolon
                        {
                          addVhdlType($2,getParsedLine(t_LIBRARY),Entry::VARIABLE_SEC,VhdlDocGen::LIBRARY,"context",0);
                        }

context_stat_1: t_CONTEXT
context_stat_1: t_CONTEXT t_Identifier

libustcont_stats: libustcont_stat                     { $$ = $1; }
libustcont_stats: libustcont_stats  libustcont_stat   { $$ = $1+"#"+$2; }

libustcont_stat: use_clause  { $$ = $1; }
libustcont_stat: lib_clause  { $$ = $1; }
libustcont_stat: context_ref { $$ = $1; }

package_instantiation_decl: t_PACKAGE t_Identifier t_IS t_NEW dot_name signature t_Semicolon
    {
      $$=" is new "+$5+$6;
      //Entry * pp=lastCompound;
      //Entry * pps=lastEntity  ;
      //assert(false);
      addVhdlType($2,getParsedLine(t_PACKAGE),Entry::VARIABLE_SEC,VhdlDocGen::INSTANTIATION,"package",$$.data());
    }
package_instantiation_decl: t_PACKAGE t_Identifier t_IS t_NEW dot_name signature  gen_assoc_list t_Semicolon
    {
      $$=" is new "+$5+$6;
      addVhdlType($2,getParsedLine(t_PACKAGE),Entry::VARIABLE_SEC,VhdlDocGen::INSTANTIATION,"package",$$.data());
    }
package_instantiation_decl: t_PACKAGE error  t_Identifier t_IS t_NEW t_Semicolon  { $$=""; }

subprogram_instantiation_decl: t_FUNCTION  t_Identifier t_IS   t_NEW dot_name  signature  t_Semicolon
    {
      $$= " is new "+$5+$6;
      addVhdlType($2,getParsedLine(t_FUNCTION),Entry::VARIABLE_SEC,VhdlDocGen::INSTANTIATION,"function ",$$.data());
    }
subprogram_instantiation_decl: t_FUNCTION  t_Identifier t_IS t_NEW dot_name  signature gen_assoc_list t_Semicolon
    {
      $$=" is new "+$5+$6;
      addVhdlType($2,getParsedLine(t_FUNCTION),Entry::VARIABLE_SEC,VhdlDocGen::INSTANTIATION,"function ",$$.data());
    }
subprogram_instantiation_decl: t_FUNCTION   t_Identifier t_IS   t_NEW error t_Semicolon { $$=""; }

signature:/*empty*/                  { $$=""; }
signature: t_LEFTBR signature1 
           t_RIGHTBR                 { $$="["+$2+" ]"; }
signature: t_LEFTBR t_RIGHTBR        { $$="[ ]"; }

signature1: t_RETURN mark            { $$="return "+$2; }
signature1: mark_stats               { $$=$1; }
signature1: mark_stats t_RETURN mark { $$=$1+" return "+$3; }

mark_stats: mark                     { $$=$1; }
mark_stats: mark_stats mark_stats_1  { $$=$1+" "+$2; }
mark_stats_1: t_Comma mark           { $$=" , "+$2; }

case_scheme:  t_CASE expr   t_GENERATE when_stats ttend  t_END t_GENERATE generate_stat_1  t_Semicolon
case_scheme:  t_CASE expr   t_GENERATE when_stats        t_END t_GENERATE generate_stat_1  t_Semicolon
case_scheme:  t_CASE error  t_GENERATE error             t_END t_GENERATE generate_stat_1  t_Semicolon

when_stats_1: t_WHEN lable choices t_Arrow generate_statement_body
when_stats_1: t_WHEN choices t_Arrow generate_statement_body
when_stats:   when_stats  when_stats_1
when_stats:   when_stats_1

ttend: t_END t_Semicolon
ttend: t_END t_Identifier t_Semicolon

conditional_signal_assignment: conditional_waveform_assignment { $$=""; }
conditional_signal_assignment: conditional_force_assignment { $$=""; }

conditional_waveform_assignment: target t_LESym wavefrm_element t_WHEN expr else_wave_list t_Semicolon
conditional_waveform_assignment: target t_LESym delay_mechanism wavefrm_element t_WHEN expr else_wave_list t_Semicolon
conditional_waveform_assignment: target t_LESym wavefrm_element t_WHEN expr t_Semicolon
conditional_waveform_assignment: target t_LESym delay_mechanism wavefrm_element t_WHEN expr t_Semicolon
conditional_waveform_assignment: target t_LESym error t_Semicolon

else_wave_list: t_ELSE expr t_WHEN expr
else_wave_list: t_ELSE expr

conditional_force_assignment:  target t_LESym t_FORCE  inout_stat expr t_WHEN expr else_stat t_Semicolon
conditional_force_assignment:  target t_LESym t_FORCE  inout_stat expr t_WHEN expr t_Semicolon

selected_signal_assignment : selected_waveform_assignment { $$=""; }
selected_signal_assignment : selected_force_assignment { $$=""; }

selected_waveform_assignment: t_WITH expr t_SELECT choice_stat
                              target t_LESym delay_stat sel_wave_list

delay_stat:
delay_stat: delay_mechanism

sel_wave_list: wavefrm_element t_WHEN choices t_Comma  sel_wave_list
sel_wave_list: sel_wave_list_1

sel_wave_list_1: wavefrm_element  t_WHEN choices t_Semicolon

selected_force_assignment: t_WITH expr t_SELECT choice_stat target t_LESym t_FORCE
                                                  inout_stat sel_var_list

inout_stat: /* empty */ { $$=""; }
inout_stat: t_IN   { $$=" in "; }
inout_stat: t_OUT { $$="out"; }

delay_mechanism : t_TRANSPORT { $$=" transport "; }
                | t_REJECT expr t_INERTIAL { $$=" reject "+$2+"inertial "; }
                |  t_INERTIAL { $$=" inertial "; }

conditional_variable_assignment : variable_assign_stat_1 t_WHEN expr else_stat t_Semicolon
conditional_variable_assignment : variable_assign_stat_1 t_WHEN expr t_Semicolon

else_stat: t_ELSE expr t_WHEN expr
else_stat: else_stat t_ELSE expr t_WHEN expr
else_stat: t_ELSE expr

selected_variable_assignment: t_WITH expr t_SELECT choice_stat select_name t_VarAsgn sel_var_list { $$=""; }

sel_var_list: expr t_WHEN choices t_Comma  sel_var_list
sel_var_list: sel_var_list_1

sel_var_list_1: expr t_WHEN choices t_Semicolon

select_name: name
           | aggregate

interface_subprogram_decl: iproc { $$ = $1; }
                         | ifunc { $$=$1; }
                         ;
iproc: t_PROCEDURE t_Identifier param { $$ = "procedure "+$2+$3; current->name=$2; }

ifunc: t_FUNCTION   func_name param   t_RETURN mark return_is
    {
      QCString s=$6;
      if (!s.isEmpty())
      {
        s.prepend(" is ");
      }
      $$=" function "+$2+$3+$5+s;
      current->name=$2;
    }
ifunc: func_prec t_FUNCTION  func_name param t_RETURN mark return_is
    {
      QCString s=$7;
      if (!s.isEmpty())
      {
        s.prepend(" is ");
      }
      $$=$1+" function "+$3+$4+" return "+$6+s;
      current->name=$3;
    }

func_name: t_Identifier   { $$=$1; }
         | t_StringLit    { $$=$1; }  // "?<"
         ;

return_is:  /* empty */       { $$="";   }
         | t_IS  t_Identifier { $$=$2;   }
         | t_IS t_Box         { $$="<>"; }

param: /* empty */ { $$=""; }
param: t_PARAMETER { $$="parameter "; }
param: t_PARAMETER { parse_sec=PARAM_SEC; }
                   t_LeftParen interf_element interf_list_1 t_RightParen
                   { parse_sec=0; }

param: t_LeftParen  interf_element interf_list_1 t_RightParen { $$="("+$2+")"; }

interface_package_decl: t_PACKAGE t_Identifier t_IS t_NEW dot_name
                        {
                          $$="package "+$2+" is new "+$5;
                          current->name=$2;
                        }
interface_package_decl: t_PACKAGE t_Identifier t_IS t_NEW dot_name gen_assoc_list 
                        { 
                          $$="package "+$2+" is new "+$5+"( ... )" ; 
                          current->name=$2; 
                        }

gen_assoc_list:         t_GENERIC t_MAP   association_list

gen_interface_list :    t_GENERIC
                        {
                          //int u=s_str.iLine;
                          parse_sec=GEN_SEC;
                        }
                        interf_list
                        {
                          QCString vo=$3;
                          parse_sec=0;
                        }

external_name: t_SLSL sig_stat external_pathname t_Colon  subtype_indic  t_SRSR
                        {
                          QCString s="<<"+$2;
                          QCString s1=$3+":"+$5+">>";
                          $$=s+s1;
                        }

sig_stat:  t_CONSTANT   { $$="constant "; }
sig_stat:  t_SIGNAL     { $$="signal ";   }
sig_stat:  t_VARIABLE   { $$="variable "; }

external_pathname: absolute_pathname  { $$=$1; }
                 | relative_pathname  { $$=$1; }
                 | package_path_name  { $$=$1; }
                 ;

absolute_pathname:  t_Dot  pathname_element_list t_Identifier  { $$="."+$2+$3; }
absolute_pathname:  t_Dot  t_Identifier  { $$="."+$2; }

relative_pathname: neg_list pathname_element_list t_Identifier { $$=$1+$2+$3; }
relative_pathname: neg_list t_Identifier { $$=$1+$2; }

neg_list:  t_Neg t_Dot          { $$="^."; }
neg_list: neg_list  t_Neg t_Dot { $$=$1+"^."; }

pathname_element: t_Identifier  { $$=$1; }
                | t_Identifier t_LeftParen expr  t_RightParen  { $$=$1+"("+$3+")"; }
                ;

pathname_element_list: pathname_element t_Dot     { $$=$1+"."; }
                     | pathname_element_list pathname_element t_Dot   { $$=$1+$2+"."; }

package_path_name: t_At dot_name { $$="@"+$2; }

tool_directive: t_ToolDir
{
// fprintf(stderr,"\n  tooldir %s",s_str.qstr.data() );
}


%%
extern FILE* yyout;
extern YYSTYPE vhdlscannerYYlval;

void vhdlscannerYYerror(const char* /*str*/)
{
  // fprintf(stderr,"\n<---error at line %d  : [ %s]   in file : %s ---->",s_str.yyLineNr,s_str.qstr.data(),s_str.fileName);
  //  exit(0);
}

void vhdlParse()
{
  vhdlscannerYYparse();
}

struct VhdlContainer*  getVhdlCont()
{
  return &s_str;
}

Entry* getVhdlCompound()
{
  if (lastEntity) return lastEntity;
  if (lastCompound) return lastCompound;
  return NULL;
}

QList<VhdlConfNode>& getVhdlConfiguration() { return  configL; }

static void addCompInst(char *n, char* instName, char* comp,int iLine)
{

  current->spec=VhdlDocGen::INSTANTIATION;
  current->section=Entry::VARIABLE_SEC;
  current->startLine=iLine;
  current->bodyLine=iLine;
  current->type=instName;                       // foo:instname e.g proto or work. proto(ttt)
  current->exception=genLabels.lower();         // |arch|label1:label2...
  current->name=n;                              // foo
  current->args=lastCompound->name;             // architecture name
  current->includeName=comp;                    // component/enity/configuration
  int u=genLabels.find("|",1);
  if (u>0)
  {
    current->write=genLabels.right(genLabels.length()-u);
    current->read=genLabels.left(u);
  }
  //printf  (" \n genlable: [%s]  inst: [%s]  name: [%s] %d\n",n,instName,comp,iLine);

  if (lastCompound)
  {
    current->args=lastCompound->name;
    if (true) // !findInstant(current->type))
    {
      initEntry(current);
      instFiles.append(new Entry(*current));
    }

    Entry *temp=current;  // hold  current pointer  (temp=oldEntry)
    current=new Entry;     // (oldEntry != current)
    delete  temp;
  }
  else
  {
    newEntry();
  }
}

static void pushLabel( QCString &label,QCString & val)
{
  label+="|";
  label+=val;
}

static QCString  popLabel(QCString & q)
{
  QCString u=q;
  int i=q.findRev("|");
  if (i<0) return "";
  q = q.left(i);
  return q;
}

static void addConfigureNode(const char* a,const char*b, bool,bool isLeaf,bool inlineConf)
{
  VhdlConfNode* co=0;
  QCString ent,arch,lab;
  QCString l=genLabels;
  ent=a;
  lab =  VhdlDocGen::parseForConfig(ent,arch);

  if (b)
  {
    ent=b;
    lab=VhdlDocGen::parseForBinding(ent,arch);
  }
  int level=0;

  if(!configL.isEmpty())
  {
    VhdlConfNode* vc=configL.getLast();
    level=vc->level;
    if (levelCounter==0)
      pushLabel(forL,ent);
    else if (level<levelCounter)
    {
      if (!isLeaf)
      {
        pushLabel(forL,ent);
      }
    }
    else if (level>levelCounter)
    {
      forL=popLabel(forL); 
    }
  }
  else
  {
    pushLabel(forL,ent);
  }


  if (inlineConf)
  {
    confName=lastCompound->name;
  }

  //fprintf(stderr,"\n[%s %d %d]\n",forL.data(),levelCounter,level);
  co=new VhdlConfNode(a,b,confName.lower().data(),forL.lower().data(),isLeaf);

  if (inlineConf)
  {
    co->isInlineConf=TRUE;
  }

  configL.append(co);

}// addConfigure

//  ------------------------------------------------------------------------------------------------------------

static bool isFuncProcProced()
{
  if (currP==VhdlDocGen::FUNCTION ||
      currP==VhdlDocGen::PROCEDURE ||
      currP==VhdlDocGen::PROCESS
     )
  {
    return TRUE;
  }
  return FALSE;
}

static void initEntry(Entry *e)
{
  e->fileName = s_str.fileName;
  e->lang=SrcLangExt_VHDL;
  isVhdlDocPending();
  initGroupInfo(e);
}

static void addProto(const char *s1,const char *s2,const char *s3,
    const char *s4,const char *s5,const char *s6)
{
  (void)s5; // avoid unused warning
  static QRegExp reg("[\\s]");
  QCString name=s2;
  QStringList ql=QStringList::split(",",name,FALSE);

  for (uint u=0;u<ql.count();u++)
  {
    Argument *arg=new Argument;
    arg->name=ql[u].utf8();
    if (s3)
    {
      arg->type=s3;
    }
    arg->type+=" ";
    arg->type+=s4;
    if (s6)
    {
      arg->type+=s6;
    }
    if (parse_sec==GEN_SEC && param_sec==0)
    {
      arg->defval="gen!";
    }

    if (parse_sec==PARAM_SEC)
    {
      assert(false);
    }

    arg->defval+=s1;
    arg->attrib="";//s6;

    current->argList->append(arg);
    current->args+=s2;
    current->args+=",";
  }
}

static void createFunction(const QCString &impure,uint64 spec,
    const QCString &fname)
{

  current->spec=spec;
  current->section=Entry::FUNCTION_SEC;

  if (impure=="impure" || impure=="pure")  
  {
    current->exception=impure;
  }

  if (parse_sec==GEN_SEC)
  {
    current->spec= VhdlDocGen::GENERIC;
    current->section=Entry::FUNCTION_SEC;
  }

  if (currP==VhdlDocGen::PROCEDURE)
  {
    current->name=impure;
    current->exception="";
  }
  else
  {
    current->name=fname;
  }

  if (spec==VhdlDocGen::PROCESS)
  {

    current->args=fname;
    current->name=impure;
    VhdlDocGen::deleteAllChars(current->args,' ');
    if (!fname.isEmpty())
    {
      QStringList q1=QStringList::split(",",fname);
      for (uint ii=0;ii<q1.count();ii++)
      {
        Argument *arg=new Argument;
        arg->name=q1[ii].utf8();
        current->argList->append(arg);
      }
    }
    return;
  }

  current->startLine=s_str.iLine;
  current->bodyLine=s_str.iLine;

}

static void addVhdlType(const QCString &name,int startLine,int section,
    uint64 spec,const char* args,const char* type,Protection prot)
{
  static QRegExp reg("[\\s]");

  if (isFuncProcProced() || VhdlDocGen::getFlowMember())   return;
    
  if (parse_sec==GEN_SEC)
  {
    spec= VhdlDocGen::GENERIC;
  }

  // more than one name   ?
  QStringList ql=QStringList::split(",",name,FALSE);

  for (uint u=0;u<ql.count();u++)
  {
    current->name=ql[u].utf8();
  

    current->startLine=startLine;
    current->bodyLine=startLine;
    current->section=section;
    current->spec=spec;
    current->fileName=s_str.fileName;
    if (current->args.isEmpty())
    {
      current->args=args;
//    current->args.replace(reg,"%"); // insert dummy chars because wihte spaces are removed
    }
    current->type=type;
//  current->type.replace(reg,"%"); // insert dummy chars because white spaces are removed
    current->protection=prot;
 
       if (!lastCompound && (section==Entry::VARIABLE_SEC) &&  (spec == VhdlDocGen::USE || spec == VhdlDocGen::LIBRARY) )
       {
         libUse.append(new Entry(*current));
         current->reset();
       }
    newEntry();
  }
}

static void newEntry()
{

  if (VhdlDocGen::isVhdlClass(current))
  {
    current_root->addSubEntry(current);
  }
  else
  {
    if (lastCompound)
    {
      lastCompound->addSubEntry(current);
    }
    else
    {
      if (lastEntity)
      {
        lastEntity->addSubEntry(current);
      }
      else
      {
        current_root->addSubEntry(current);
      }
    }
  }
  current = new Entry ;
  initEntry(current);
}

void createFlow()
{
  if (!VhdlDocGen::getFlowMember()) 
  {
    return;
  }
  QCString q,ret;

  if (currP==VhdlDocGen::FUNCTION)
  {
    q=":function( ";
    FlowChart::alignFuncProc(q,tempEntry->argList,true);
    q+=")";
  }
  else if (currP==VhdlDocGen::PROCEDURE)
  {
    q=":procedure (";    
    FlowChart::alignFuncProc(q,tempEntry->argList,false);
    q+=")";
  }
  else  
  {  
    q=":process( "+tempEntry->args;
    q+=")";
  }

  q.prepend(VhdlDocGen::getFlowMember()->name().data());

  FlowChart::addFlowChart(FlowChart::START_NO,q,0);

  if (currP==VhdlDocGen::FUNCTION)
  {
    ret="end function ";  
  }
  else if (currP==VhdlDocGen::PROCEDURE)
  {
    ret="end procedure";
  }
  else 
  {
    ret="end process ";
  }

  FlowChart::addFlowChart(FlowChart::END_NO,ret,0);
  //  FlowChart::printFlowList();
  FlowChart::writeFlowChart();  
  currP=0;
}