More robust VST parser.

* Bug: In CRL Core, in VstParserGrammar.yy & VstParserScanner.ll, accurate
    error message positions (file & line numbers).
      When generating error message, we cannot pass char* on variables that
    will be deallocated by the throw. So generate a string that will be
    copied along with the exception. That problems explain numerous
    core-dump when encountering syntaxes errors in the file.
This commit is contained in:
Jean-Paul Chaput 2014-12-11 23:56:59 +01:00
parent 978315c017
commit 8eac4b4b6f
2 changed files with 313 additions and 289 deletions

View File

@ -1,46 +1,21 @@
%{ %{
// This file is part of the Coriolis Software.
// This file is part of the Coriolis Project. // Copyright (c) UPMC 2008-2014, All Rights Reserved
// Copyright (C) Laboratoire LIP6 - Departement ASIM
// Universite Pierre et Marie Curie
// //
// Main contributors : // +-----------------------------------------------------------------+
// Christophe Alexandre <Christophe.Alexandre@lip6.fr> // | C O R I O L I S |
// Sophie Belloeil <Sophie.Belloeil@lip6.fr> // | Alliance / Hurricane Interface |
// Hugo Clément <Hugo.Clement@lip6.fr> // | Yacc Grammar for Alliance Structural VHDL |
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr> // | |
// Damien Dupuis <Damien.Dupuis@lip6.fr> // | Author : Jean-Paul CHAPUT |
// Christian Masson <Christian.Masson@lip6.fr> // | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// Marek Sroka <Marek.Sroka@lip6.fr> // | =============================================================== |
// // | Yacc : "./VstParserGrammar.yy" |
// The Coriolis Project is free software; you can redistribute it // | |
// and/or modify it under the terms of the GNU General Public License // | This file is based on the Alliance VHDL parser written by |
// as published by the Free Software Foundation; either version 2 of // | L.A. Tabusse, Vuong H.N., P. Bazargan-Sabet & D. Hommais |
// the License, or (at your option) any later version. // +-----------------------------------------------------------------+
//
// The Coriolis Project is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with the Coriolis Project; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA
//
// License-Tag
// Authors-Tag
// ===================================================================
//
// This file is based on the Alliance VHDL parser written by
// L.A. Tabusse, Vuong H.N., P. Bazargan-Sabet & D. Hommais.
//
// Yacc Rules for Alliance Structural VHDL.
//
// ===================================================================
//
// $Id$
#include <stdio.h> #include <stdio.h>
@ -49,9 +24,10 @@
#include <sstream> #include <sstream>
#include <map> #include <map>
#include <vector> #include <vector>
#include <queue> #include <deque>
using namespace std; using namespace std;
#include "hurricane/Warning.h"
#include "hurricane/Net.h" #include "hurricane/Net.h"
#include "hurricane/Cell.h" #include "hurricane/Cell.h"
#include "hurricane/Plug.h" #include "hurricane/Plug.h"
@ -68,24 +44,30 @@ using namespace CRL;
// Symbols from Flex which should be substituted. // Symbols from Flex which should be substituted.
# define yyrestart VSTrestart #define yyrestart VSTrestart
# define yytext VSTtext #define yytext VSTtext
# define yywrap VSTwrap #define yywrap VSTwrap
# define yyin VSTin #define yyin VSTin
extern void ClearVstIdentifiers ();
extern int yylex (); extern int yylex ();
extern int yywrap (); extern int yywrap ();
extern void yyrestart ( FILE* ); extern void yyrestart ( FILE* );
extern char* yytext; extern char* yytext;
extern FILE* yyin; extern FILE* yyin;
int vhdLineNumber = 1;
namespace { namespace {
int yyerror ( const char* message );
} // Anonymous namespace.
namespace Vst {
extern void incVhdLineNumber ();
extern void ClearIdentifiers ();
class Constraint { class Constraint {
private: private:
@ -134,14 +116,15 @@ namespace {
typedef map<Cell*,VectorMap> CellVectorMap; typedef map<Cell*,VectorMap> CellVectorMap;
AllianceFramework* __framework;
class YaccState { class YaccState {
public: public:
string _vhdFileName;
int _vhdLineNumber;
int _errorCount; int _errorCount;
int _maxErrors; int _maxErrors;
queue<Name> _cellQueue; deque<Name> _cellQueue;
Catalog::State* _state; Catalog::State* _state;
Cell* _cell; Cell* _cell;
Cell* _masterCell; Cell* _masterCell;
@ -155,26 +138,39 @@ namespace {
bool _firstPass; bool _firstPass;
bool _behavioral; bool _behavioral;
public: public:
YaccState () YaccState ( const string& vhdFileName )
: _errorCount(0) : _vhdFileName (vhdFileName)
, _maxErrors(10) , _vhdLineNumber (1)
, _cellQueue() , _errorCount (0)
, _state(NULL) , _maxErrors (10)
, _cell(NULL) , _cellQueue ()
, _masterCell(NULL) , _state (NULL)
, _instance(NULL) , _cell (NULL)
, _constraint() , _masterCell (NULL)
, _instance (NULL)
, _constraint ()
, _identifiersList() , _identifiersList()
, _cellVectorMap() , _cellVectorMap ()
, _instanceNets() , _instanceNets ()
, _masterNets() , _masterNets ()
, _masterPort(true) , _masterPort (true)
, _firstPass(true) , _firstPass (true)
, _behavioral(false) , _behavioral (false)
{ } { }
bool pushCell ( Name );
}; };
bool YaccState::pushCell ( Name cellName )
{
for ( size_t i=0 ; i<_cellQueue.size(); ++i ) {
if (_cellQueue[i] == cellName) return false;
}
_cellQueue.push_back( cellName );
return true;
}
class YaccStateStack : public vector<YaccState*> { class YaccStateStack : public vector<YaccState*> {
public: public:
YaccState* operator->() { return back(); }; YaccState* operator->() { return back(); };
@ -182,18 +178,15 @@ namespace {
}; };
YaccStateStack __ys; YaccStateStack states;
AllianceFramework* framework;
void Error ( int code, const string& name );
int yyerror ( const char* message );
void VstError ( int code, const string& name );
Net* getNet ( Cell* cell, const string& name ); Net* getNet ( Cell* cell, const string& name );
void SetNetType ( Net* net ); void SetNetType ( Net* net );
} } // Vst namespace.
%} %}
@ -388,7 +381,7 @@ entity_declaration
Semicolon_ERR Semicolon_ERR
| ENTITY | ENTITY
error error
{ VstError ( 2, "<no parameter>" ); } { Vst::Error ( 2, "<no parameter>" ); }
; ;
.generic_clause. .generic_clause.
@ -426,8 +419,10 @@ formal_generic_element
type_mark type_mark
.constraint. .constraint.
generic_VarAsgn__expression generic_VarAsgn__expression
{ __ys->_constraint.UnSet (); { if (not Vst::states->_firstPass) {
__ys->_identifiersList.clear (); Vst::states->_constraint.UnSet();
Vst::states->_identifiersList.clear();
}
} }
| error | error
; ;
@ -451,7 +446,7 @@ constraint
range range
: abstractlit : abstractlit
direction direction
abstractlit { __ys->_constraint.Set ( $1, $2, $3 ); } abstractlit { if (not Vst::states->_firstPass) Vst::states->_constraint.Set( $1, $2, $3 ); }
; ;
direction direction
@ -473,7 +468,7 @@ port_clause
| PORT | PORT
error error
Semicolon_ERR Semicolon_ERR
{ VstError ( 3, "<no parameter>" ); } { Vst::Error ( 3, "<no parameter>" ); }
; ;
formal_port_list formal_port_list
@ -496,36 +491,36 @@ formal_port_element
type_mark type_mark
.constraint. .constraint.
.BUS. .BUS.
{ if ( !__ys->_firstPass ) { { if (not Vst::states->_firstPass) {
Net::Direction modeDirection = (Net::Direction::Code)$4; Net::Direction modeDirection = (Net::Direction::Code)$4;
Net::Direction typeDirection = (Net::Direction::Code)$5; Net::Direction typeDirection = (Net::Direction::Code)$5;
Net::Direction direction = (Net::Direction::Code)(modeDirection | typeDirection); Net::Direction direction = (Net::Direction::Code)(modeDirection | typeDirection);
for ( unsigned int i=0 ; i < __ys->_identifiersList.size() ; i++ ) { for ( unsigned int i=0 ; i < Vst::states->_identifiersList.size() ; i++ ) {
if ( __ys->_constraint.IsSet() ) { if ( Vst::states->_constraint.IsSet() ) {
int j; int j;
for ( __ys->_constraint.Init(j) ; __ys->_constraint.End(j) ; __ys->_constraint.Next(j) ) { for ( Vst::states->_constraint.Init(j) ; Vst::states->_constraint.End(j) ; Vst::states->_constraint.Next(j) ) {
ostringstream name; ostringstream name;
name << *__ys->_identifiersList[i] << "(" << j << ")"; name << *Vst::states->_identifiersList[i] << "(" << j << ")";
Net* net = Net::create ( __ys->_cell, name.str() ); Net* net = Net::create ( Vst::states->_cell, name.str() );
net->setDirection ( direction ); net->setDirection ( direction );
net->setExternal ( true ); net->setExternal ( true );
SetNetType ( net ); Vst::SetNetType ( net );
__ys->_cellVectorMap[__ys->_cell][*__ys->_identifiersList[i]].push_back ( net ); Vst::states->_cellVectorMap[Vst::states->_cell][*Vst::states->_identifiersList[i]].push_back ( net );
NetExtension::addPort ( net, name.str() ); NetExtension::addPort ( net, name.str() );
} }
} else { } else {
Net* net = Net::create ( __ys->_cell, *__ys->_identifiersList[i] ); Net* net = Net::create ( Vst::states->_cell, *Vst::states->_identifiersList[i] );
net->setDirection ( direction ); net->setDirection ( direction );
net->setExternal ( true ); net->setExternal ( true );
SetNetType ( net ); Vst::SetNetType ( net );
__ys->_cellVectorMap[__ys->_cell][*__ys->_identifiersList[i]].push_back ( net ); Vst::states->_cellVectorMap[Vst::states->_cell][*Vst::states->_identifiersList[i]].push_back ( net );
NetExtension::addPort ( net, *__ys->_identifiersList[i] ); NetExtension::addPort ( net, *Vst::states->_identifiersList[i] );
} }
} }
}
__ys->_constraint.UnSet (); Vst::states->_constraint.UnSet ();
__ys->_identifiersList.clear (); Vst::states->_identifiersList.clear ();
}
} }
| error | error
{ /* Reject tokens until the sync token Semicolon is found. */ { /* Reject tokens until the sync token Semicolon is found. */
@ -534,35 +529,35 @@ formal_port_element
} while ( (yychar != Semicolon) && (yychar != 0) ); } while ( (yychar != Semicolon) && (yychar != 0) );
yyerrok; yyerrok;
VstError ( 6, "<no parameter>" ); Vst::Error ( 6, "<no parameter>" );
} }
; ;
architecture_body architecture_body
: ARCHITECTURE : ARCHITECTURE
simple_name simple_name
{ if ( ( __ys->_behavioral ) { if ( ( Vst::states->_behavioral )
|| ( __ys->_state->isFlattenLeaf() ) || ( Vst::states->_state->isFlattenLeaf() )
|| ( __ys->_state->getDepth() <= 0 ) || ( Vst::states->_state->getDepth() <= 0 )
) YYACCEPT; ) YYACCEPT;
} }
OF OF
simple_name simple_name
IS IS
{ if ( __ys->_cell->getName() != *$5 ) VstError ( 1, *$5 ); } { if ( Vst::states->_cell->getName() != *$5 ) Vst::Error ( 1, *$5 ); }
architecture_declarative_part architecture_declarative_part
_BEGIN _BEGIN
{ if ( __ys->_firstPass ) YYACCEPT; } { /*if (Vst::states->_firstPass) YYACCEPT;*/ }
architecture_statement_part architecture_statement_part
END_ERR END_ERR
.simple_name. .simple_name.
Semicolon_ERR Semicolon_ERR
{ if ( ( $13 != NULL ) && ( *$13 != *$2 ) ) { if ( ( $13 != NULL ) && ( *$13 != *$2 ) )
VstError ( 7, *$13 ); Vst::Error ( 7, *$13 );
} }
| ARCHITECTURE | ARCHITECTURE
error error
{ VstError ( 8, "<no parameter>" ); } { Vst::Error ( 8, "<no parameter>" ); }
; ;
architecture_declarative_part architecture_declarative_part
@ -580,7 +575,7 @@ block_declaration_item
| component_declaration | component_declaration
| error | error
Semicolon_ERR Semicolon_ERR
{ VstError ( 9, "<no parameter>" ); } { Vst::Error ( 9, "<no parameter>" ); }
; ;
signal_declaration signal_declaration
@ -591,43 +586,43 @@ signal_declaration
.constraint. .constraint.
.BUS. .BUS.
Semicolon_ERR Semicolon_ERR
{ if ( !__ys->_firstPass ) { { if (not Vst::states->_firstPass) {
Net::Direction direction = (Net::Direction::Code)$4; Net::Direction direction = (Net::Direction::Code)$4;
for ( unsigned int i=0 ; i < __ys->_identifiersList.size() ; i++ ) { for ( unsigned int i=0 ; i < Vst::states->_identifiersList.size() ; i++ ) {
if ( __ys->_constraint.IsSet() ) { if ( Vst::states->_constraint.IsSet() ) {
int j; int j;
for ( __ys->_constraint.Init(j) ; __ys->_constraint.End(j) ; __ys->_constraint.Next(j) ) { for ( Vst::states->_constraint.Init(j) ; Vst::states->_constraint.End(j) ; Vst::states->_constraint.Next(j) ) {
ostringstream name; ostringstream name;
name << *__ys->_identifiersList[i] << "(" << j << ")"; name << *Vst::states->_identifiersList[i] << "(" << j << ")";
Net* net = Net::create ( __ys->_cell, name.str() ); Net* net = Net::create ( Vst::states->_cell, name.str() );
net->setDirection ( direction ); net->setDirection ( direction );
net->setExternal ( false ); net->setExternal ( false );
SetNetType ( net ); Vst::SetNetType ( net );
__ys->_cellVectorMap[__ys->_cell][*__ys->_identifiersList[i]].push_back ( net ); Vst::states->_cellVectorMap[Vst::states->_cell][*Vst::states->_identifiersList[i]].push_back ( net );
} }
} else { } else {
Net* net = Net::create ( __ys->_cell, *__ys->_identifiersList[i] ); Net* net = Net::create ( Vst::states->_cell, *Vst::states->_identifiersList[i] );
net->setDirection ( direction ); net->setDirection ( direction );
net->setExternal ( false ); net->setExternal ( false );
SetNetType ( net ); Vst::SetNetType ( net );
__ys->_cellVectorMap[__ys->_cell][*__ys->_identifiersList[i]].push_back ( net ); Vst::states->_cellVectorMap[Vst::states->_cell][*Vst::states->_identifiersList[i]].push_back ( net );
} }
} }
} }
__ys->_constraint.UnSet (); Vst::states->_constraint.UnSet ();
__ys->_identifiersList.clear (); Vst::states->_identifiersList.clear ();
} }
; ;
component_declaration component_declaration
: COMPONENT : COMPONENT
Identifier Identifier
{ if ( __ys->_firstPass ) { { if (Vst::states->_firstPass) {
if ( !__framework->getCell(*$2,Catalog::State::Views|Catalog::State::InMemory) ) if (not Vst::framework->getCell(*$2,Catalog::State::Views|Catalog::State::InMemory))
__ys->_cellQueue.push ( *$2 ); Vst::states->pushCell( *$2 );
} else { } else {
__ys->_masterCell = __framework->getCell ( *$2, Catalog::State::Views ); Vst::states->_masterCell = Vst::framework->getCell ( *$2, Catalog::State::Views );
} }
} }
.generic_clause. .generic_clause.
@ -666,25 +661,25 @@ local_port_element
type_mark type_mark
.constraint. .constraint.
.BUS. .BUS.
{ if ( !__ys->_firstPass ) { { if (not Vst::states->_firstPass) {
for ( unsigned int i=0 ; i < __ys->_identifiersList.size() ; i++ ) { for ( unsigned int i=0 ; i < Vst::states->_identifiersList.size() ; i++ ) {
if ( __ys->_constraint.IsSet() ) { if ( Vst::states->_constraint.IsSet() ) {
int j; int j;
for ( __ys->_constraint.Init(j) ; __ys->_constraint.End(j) ; __ys->_constraint.Next(j) ) { for ( Vst::states->_constraint.Init(j) ; Vst::states->_constraint.End(j) ; Vst::states->_constraint.Next(j) ) {
ostringstream name; ostringstream name;
name << *__ys->_identifiersList[i] << "(" << j << ")"; name << *Vst::states->_identifiersList[i] << "(" << j << ")";
Net* net = getNet ( __ys->_masterCell, name.str() ); Net* net = Vst::getNet ( Vst::states->_masterCell, name.str() );
__ys->_cellVectorMap[__ys->_masterCell][*__ys->_identifiersList[i]].push_back ( net ); Vst::states->_cellVectorMap[Vst::states->_masterCell][*Vst::states->_identifiersList[i]].push_back ( net );
} }
} else { } else {
Net* net = getNet ( __ys->_masterCell, *__ys->_identifiersList[i] ); Net* net = Vst::getNet ( Vst::states->_masterCell, *Vst::states->_identifiersList[i] );
__ys->_cellVectorMap[__ys->_masterCell][*__ys->_identifiersList[i]].push_back ( net ); Vst::states->_cellVectorMap[Vst::states->_masterCell][*Vst::states->_identifiersList[i]].push_back ( net );
} }
} }
} }
__ys->_constraint.UnSet (); Vst::states->_constraint.UnSet ();
__ys->_identifiersList.clear (); Vst::states->_identifiersList.clear ();
} }
| error | error
{ /* Reject tokens until the sync token Semicolon is found. */ { /* Reject tokens until the sync token Semicolon is found. */
@ -693,7 +688,7 @@ local_port_element
} while ( (yychar != Semicolon) && (yychar != 0) ); } while ( (yychar != Semicolon) && (yychar != 0) );
yyerrok; yyerrok;
VstError ( 6, "<no parameter>" ); Vst::Error ( 6, "<no parameter>" );
} }
; ;
@ -711,21 +706,36 @@ concurrent_statement
: component_instantiation_statement : component_instantiation_statement
| error | error
Semicolon_ERR Semicolon_ERR
{ VstError (18, "<no parameter>"); } { Vst::Error (18, "<no parameter>"); }
; ;
component_instantiation_statement component_instantiation_statement
: a_label : a_label
simple_name simple_name
{ __ys->_masterCell = __framework->getCell ( *$2, Catalog::State::Views|Catalog::State::InMemory ); { if (not Vst::states->_firstPass) {
if ( !__ys->_masterCell ) Vst::states->_masterCell = Vst::framework->getCell( *$2, Catalog::State::Views|Catalog::State::InMemory );
throw Error ( "CParsVst(), Line %d:\n" if (not Vst::states->_masterCell) {
" Model cell %s of instance %s has not been defined " ostringstream message;
"in the component list." message << "CParsVst() VHDL Parser - File:<" << Vst::states->_vhdFileName
, vhdLineNumber, *$2->c_str(), *$1->c_str() << "> Line:" << Vst::states->_vhdLineNumber << "\n"
); << " Model cell " << *$2 << " of instance "
__ys->_instance = Instance::create ( __ys->_cell, *$1, __ys->_masterCell ); << *$1 << " has not been defined in the component list.";
__ys->_cell->setTerminal ( false ); throw Error( message.str() );
}
Vst::states->_instance = Instance::create( Vst::states->_cell, *$1, Vst::states->_masterCell );
Vst::states->_cell->setTerminal( false );
} else {
if (not Vst::framework->getCell(*$2,Catalog::State::Views|Catalog::State::InMemory)) {
if (Vst::states->pushCell(*$2)) {
ostringstream message;
message << "CParsVst() VHDL Parser - File:<" << Vst::states->_vhdFileName
<< "> Line:" << Vst::states->_vhdLineNumber << "\n"
<< " Model cell " << *$2 << " of instance "
<< *$1 << " has not been defined in the component list.";
cerr << Warning( message.str() );
}
}
}
} }
.generic_map_aspect. .generic_map_aspect.
.port_map_aspect. .port_map_aspect.
@ -891,28 +901,36 @@ association_list
association_element association_element
: formal_port_name : formal_port_name
Arrow Arrow
{ __ys->_masterPort = false; } { if (not Vst::states->_firstPass) Vst::states->_masterPort = false; }
actual_port_name actual_port_name
{ if ( __ys->_masterNets.size() != __ys->_instanceNets.size() ) { if (not Vst::states->_firstPass) {
throw Error ( "CParsVst(), line %d:\n" if ( Vst::states->_masterNets.size() != Vst::states->_instanceNets.size() ) {
" Port map assignment discrepency." ostringstream message;
, vhdLineNumber message << "CParsVst() VHDL Parser - File:<" << Vst::states->_vhdFileName.c_str()
); << "> Line:" << Vst::states->_vhdLineNumber << "\n"
<< " Port map assignment discrepency "
for ( unsigned int i=0 ; i < __ys->_masterNets.size() ; i++ ) << "instance:" << Vst::states->_instanceNets.size()
if ( not __ys->_masterNets[i]->isGlobal() << " vs. model:" << Vst::states->_masterNets.size();
or (__ys->_masterNets[i]->getName() != __ys->_instanceNets[i]->getName()) ) throw Error( message.str() );
__ys->_instance->getPlug ( __ys->_masterNets[i] )->setNet ( __ys->_instanceNets[i] ); }
__ys->_masterPort = true; for ( unsigned int i=0 ; i < Vst::states->_masterNets.size() ; i++ )
__ys->_masterNets.clear (); if ( not Vst::states->_masterNets[i]->isGlobal()
__ys->_instanceNets.clear (); or (Vst::states->_masterNets[i]->getName() != Vst::states->_instanceNets[i]->getName()) )
Vst::states->_instance->getPlug ( Vst::states->_masterNets[i] )->setNet ( Vst::states->_instanceNets[i] );
Vst::states->_masterPort = true;
Vst::states->_masterNets.clear ();
Vst::states->_instanceNets.clear ();
}
} }
| actual_port_name | actual_port_name
{ throw Error ( "CParsVst(), line %d:\n" { ostringstream message;
" While processing %s: implicit connexions are not allowed.\n" message << "CParsVst() VHDL Parser - File<" << Vst::states->_vhdFileName
, vhdLineNumber, getString(__ys->_instance->getName()).c_str() << ">, Line:" << Vst::states->_vhdLineNumber << "\n"
); << " While processing " << Vst::states->_instance->getName()
<< ": implicit connexions are not allowed.\n";
throw Error( message.str() );
} }
| error | error
{ /* Reject tokens until the sync token Comma is found. */ { /* Reject tokens until the sync token Comma is found. */
@ -921,7 +939,7 @@ association_element
} while ( (yychar != Comma) && (yychar != 0) ); } while ( (yychar != Comma) && (yychar != 0) );
yyerrok; yyerrok;
VstError ( 31, "<no parameter>" ); Vst::Error ( 31, "<no parameter>" );
} }
; ;
@ -935,15 +953,17 @@ actual_port_name
name name
: simple_name : simple_name
{ if ( __ys->_masterPort ) { { if (not Vst::states->_firstPass) {
PinVector& nets = __ys->_cellVectorMap[__ys->_masterCell][*$1]; if ( Vst::states->_masterPort ) {
for ( unsigned int i=0 ; i < nets.size() ; i++ ) { Vst::PinVector& nets = Vst::states->_cellVectorMap[Vst::states->_masterCell][*$1];
__ys->_masterNets.push_back ( nets[i] ); for ( unsigned int i=0 ; i < nets.size() ; i++ ) {
} Vst::states->_masterNets.push_back ( nets[i] );
} else { }
PinVector& nets = __ys->_cellVectorMap[__ys->_cell][*$1]; } else {
for ( unsigned int i=0 ; i < nets.size() ; i++ ) { Vst::PinVector& nets = Vst::states->_cellVectorMap[Vst::states->_cell][*$1];
__ys->_instanceNets.push_back ( nets[i] ); for ( unsigned int i=0 ; i < nets.size() ; i++ ) {
Vst::states->_instanceNets.push_back ( nets[i] );
}
} }
} }
} }
@ -956,26 +976,30 @@ indexed_name
LeftParen LeftParen
abstractlit abstractlit
RightParen_ERR RightParen_ERR
{ ostringstream name; { if (not Vst::states->_firstPass) {
name << *$1 << "(" << $3 << ")"; ostringstream name;
if ( __ys->_masterPort ) name << *$1 << "(" << $3 << ")";
__ys->_masterNets.push_back ( getNet(__ys->_masterCell,name.str()) ); if ( Vst::states->_masterPort )
else Vst::states->_masterNets.push_back ( Vst::getNet(Vst::states->_masterCell,name.str()) );
__ys->_instanceNets.push_back ( getNet(__ys->_cell,name.str()) ); else
Vst::states->_instanceNets.push_back ( Vst::getNet(Vst::states->_cell,name.str()) );
}
} }
; ;
slice_name slice_name
: simple_name : simple_name
constraint constraint
{ int j; { if (not Vst::states->_firstPass) {
for ( __ys->_constraint.Init(j) ; __ys->_constraint.End(j) ; __ys->_constraint.Next(j) ) { int j;
ostringstream name; for ( Vst::states->_constraint.Init(j) ; Vst::states->_constraint.End(j) ; Vst::states->_constraint.Next(j) ) {
name << *$1 << "(" << j << ")"; ostringstream name;
if ( __ys->_masterPort ) name << *$1 << "(" << j << ")";
__ys->_masterNets.push_back ( getNet(__ys->_masterCell,name.str()) ); if ( Vst::states->_masterPort )
else Vst::states->_masterNets.push_back ( Vst::getNet(Vst::states->_masterCell,name.str()) );
__ys->_instanceNets.push_back ( getNet(__ys->_cell,name.str()) ); else
Vst::states->_instanceNets.push_back ( Vst::getNet(Vst::states->_cell,name.str()) );
}
} }
} }
; ;
@ -1072,7 +1096,7 @@ type_mark
; ;
identifier_list identifier_list
: Identifier { __ys->_identifiersList.push_back ( $1 ); } : Identifier { if (not Vst::states->_firstPass) Vst::states->_identifiersList.push_back( $1 ); }
...identifier.. ...identifier..
; ;
@ -1080,7 +1104,7 @@ identifier_list
: /*empty*/ : /*empty*/
| ...identifier.. | ...identifier..
Comma Comma
Identifier { __ys->_identifiersList.push_back ( $3 ); } Identifier { if (not Vst::states->_firstPass) Vst::states->_identifiersList.push_back( $3 ); }
; ;
a_label a_label
@ -1127,32 +1151,44 @@ namespace {
int yyerror ( const char* message ) int yyerror ( const char* message )
{ {
throw Error ( "CParsVst():\n %s before %s at line %d.\n" ostringstream formatted;
, message, yytext, vhdLineNumber ); formatted << "CParsVst() - VHDL Parser, File:<" << Vst::states->_vhdFileName
<< ">, Line:" << Vst::states->_vhdLineNumber << "\n "
<< message << " before " << yytext << ".\n";
throw Hurricane::Error( formatted.str() );
return 0; return 0;
} }
} // Anonymous namespace.
namespace Vst {
void incVhdLineNumber ()
{ ++states->_vhdLineNumber; }
// --------------------------------------------------------------- // ---------------------------------------------------------------
// Function : "VstError()". // Function : "Vst::Error()".
// //
// Manage errors from wich we can recover and continue a little // Manage errors from wich we can recover and continue a little
// while. // while.
void VstError ( int code, const string& name ) void Error ( int code, const string& name )
{ {
__ys->_errorCount++; states->_errorCount++;
if ( __ys->_errorCount >= __ys->_maxErrors ) if ( states->_errorCount >= states->_maxErrors )
throw Error ( "CParsVst(): Too many errors occured.\n" ); throw Hurricane::Error ( "CParsVst() VHDL Parser, Too many errors occured.\n" );
if ( code < 100 ) if ( code < 100 )
cerr << "[ERROR] CParsVst(): Code " << code << " line " << vhdLineNumber << " :\n "; cerr << "[ERROR] CParsVst() VHDL Parser, File:<" << states->_vhdFileName
<< ">, Line:%d" << states->_vhdLineNumber << " Code:" << code << " :\n ";
else { else {
if (code < 200) if (code < 200)
cerr << "[ERROR] CParsVst(): Code " << code << " :\n "; cerr << "[ERROR] CParsVst() VHDL Parser, Code:" << code << " :\n ";
} }
switch ( code ) { switch ( code ) {
@ -1183,13 +1219,11 @@ namespace {
case 76: cerr << "Instance \"" << name << "\"mismatch with model." << endl; break; case 76: cerr << "Instance \"" << name << "\"mismatch with model." << endl; break;
default: cerr << "Syntax error." << endl; break; default: cerr << "Syntax error." << endl; break;
case 200: case 200:
throw Error ( "Error(s) occured.\n" ); throw Hurricane::Error ( "Error(s) occured.\n" );
} }
} }
// --------------------------------------------------------------- // ---------------------------------------------------------------
// Function : "getNet()". // Function : "getNet()".
@ -1197,39 +1231,38 @@ namespace {
{ {
Net* net = cell->getNet ( Name(name) ); Net* net = cell->getNet ( Name(name) );
if ( !net ) { if ( !net ) {
throw Error ( "CParsVst(), line %d:\n" ostringstream message;
" No net \"%s\" in cell \"%s\".\n" message << "CParsVst() VHDL Parser, File:<" << states->_vhdFileName
, vhdLineNumber << "> Line:" << states->_vhdLineNumber
, name.c_str() << "\n"
, getString(cell->getName()).c_str() << " No net \"" << name
); << "\" in cell \"" << cell->getName() << "\".\n";
throw Hurricane::Error( message.str() );
} }
return net; return net;
} }
// --------------------------------------------------------------- // ---------------------------------------------------------------
// Function : "SetNetType()". // Function : "SetNetType()".
void SetNetType ( Net* net ) void SetNetType ( Net* net )
{ {
if ( __framework->isPOWER(net->getName()) ) { if ( framework->isPOWER(net->getName()) ) {
net->setType ( Net::Type::POWER ); net->setType ( Net::Type::POWER );
net->setGlobal ( true ); net->setGlobal ( true );
} else if ( __framework->isGROUND(net->getName()) ) { } else if ( framework->isGROUND(net->getName()) ) {
net->setType ( Net::Type::GROUND ); net->setType ( Net::Type::GROUND );
net->setGlobal ( true ); net->setGlobal ( true );
} else if ( __framework->isCLOCK(net->getName()) ) { } else if ( framework->isCLOCK(net->getName()) ) {
net->setType ( Net::Type::CLOCK ); net->setType ( Net::Type::CLOCK );
} else } else
net->setType ( Net::Type::LOGICAL ); net->setType ( Net::Type::LOGICAL );
} }
} } // Vst namespace.
@ -1242,27 +1275,27 @@ namespace CRL {
void vstParser ( const string cellPath, Cell *cell ) void vstParser ( const string cellPath, Cell *cell )
{ {
cmess2 << " " << tab << "+ " << cellPath << endl; tab++; cmess2 << " " << tab << "+ " << cellPath << " (childs)" << endl; tab++;
static bool firstCall = true; static bool firstCall = true;
if ( firstCall ) { if ( firstCall ) {
firstCall = false; firstCall = false;
__framework = AllianceFramework::get (); Vst::framework = AllianceFramework::get ();
} }
__ys.push_back ( new YaccState() ); Vst::states.push_back ( new Vst::YaccState(cellPath) );
if ( ( cellPath.size() > 4 ) && ( !cellPath.compare(cellPath.size()-4,4,".vbe") ) ) if ( ( cellPath.size() > 4 ) && ( !cellPath.compare(cellPath.size()-4,4,".vbe") ) )
__ys->_behavioral = true; Vst::states->_behavioral = true;
CatalogProperty *sprop = CatalogProperty *sprop =
(CatalogProperty*)cell->getProperty ( CatalogProperty::getPropertyName() ); (CatalogProperty*)cell->getProperty ( CatalogProperty::getPropertyName() );
if ( sprop == NULL ) if ( sprop == NULL )
throw Error ( "Missing CatalogProperty in cell %s.\n" , getString(cell->getName()).c_str() ); throw Error ( "Missing CatalogProperty in cell %s.\n" , getString(cell->getName()).c_str() );
__ys->_state = sprop->getState (); Vst::states->_state = sprop->getState ();
__ys->_state->setLogical ( true ); Vst::states->_state->setLogical ( true );
__ys->_cell = cell; Vst::states->_cell = cell;
IoFile ccell ( cellPath ); IoFile ccell ( cellPath );
ccell.open ( "r" ); ccell.open ( "r" );
@ -1270,24 +1303,22 @@ void vstParser ( const string cellPath, Cell *cell )
if ( !firstCall ) yyrestart ( VSTin ); if ( !firstCall ) yyrestart ( VSTin );
yyparse (); yyparse ();
bool hasInstances = false; while ( !Vst::states->_cellQueue.empty() ) {
while ( !__ys->_cellQueue.empty() ) { if ( !Vst::framework->getCell ( getString(Vst::states->_cellQueue.front())
hasInstances = true; , Catalog::State::Views
if ( !__framework->getCell ( getString(__ys->_cellQueue.front()) , Vst::states->_state->getDepth()-1) ) {
, Catalog::State::Views throw Error ( "CParsVst() VHDL Parser:\n"
, __ys->_state->getDepth()-1) ) { " Unable to find cell \"%s\", please check your <.coriolis2/settings.py>.\n"
throw Error ( "CParsVst():\n" , getString(Vst::states->_cellQueue.front()).c_str()
" Unable to find cell \"%s\", please check your <.environment.alliance.xml>.\n"
, getString(__ys->_cellQueue.front()).c_str()
); );
} }
__ys->_cellQueue.pop (); Vst::states->_cellQueue.pop_front();
} }
if ( hasInstances ) cmess2 << " " << --tab << "+ " << cellPath << endl; cmess2 << " " << --tab << "+ " << cellPath << " (loading)" << endl;
else --tab;
__ys->_firstPass = false; Vst::states->_firstPass = false;
Vst::states->_vhdLineNumber = 1;
ccell.close (); ccell.close ();
ccell.open ( "r" ); ccell.open ( "r" );
yyin = ccell.getFile (); yyin = ccell.getFile ();
@ -1295,9 +1326,14 @@ void vstParser ( const string cellPath, Cell *cell )
UpdateSession::open (); UpdateSession::open ();
yyparse (); yyparse ();
UpdateSession::close (); UpdateSession::close ();
ClearVstIdentifiers ();
__ys.pop_back(); forEach ( Net*, inet, Vst::states->_cell->getNets() ) {
cerr << *inet << endl;
}
Vst::ClearIdentifiers ();
Vst::states.pop_back();
ccell.close (); ccell.close ();
} }

View File

@ -3,47 +3,25 @@
%{ %{
// This file is part of the Coriolis Project. // This file is part of the Coriolis Software.
// Copyright (C) Laboratoire LIP6 - Departement ASIM // Copyright (c) UPMC 2008-2014, All Rights Reserved
// Universite Pierre et Marie Curie
// //
// Main contributors : // +-----------------------------------------------------------------+
// Christophe Alexandre <Christophe.Alexandre@lip6.fr> // | C O R I O L I S |
// Sophie Belloeil <Sophie.Belloeil@lip6.fr> // | Alliance / Hurricane Interface |
// Hugo Clément <Hugo.Clement@lip6.fr> // | |
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr> // | Author : Jean-Paul CHAPUT |
// Damien Dupuis <Damien.Dupuis@lip6.fr> // | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// Christian Masson <Christian.Masson@lip6.fr> // | =============================================================== |
// Marek Sroka <Marek.Sroka@lip6.fr> // | Lex : "./VstParserScanner.ll" |
// // | |
// The Coriolis Project is free software; you can redistribute it // | This file is based on the Alliance VHDL parser written by |
// and/or modify it under the terms of the GNU General Public License // | L.A. Tabusse, Vuong H.N., P. Bazargan-Sabet & D. Hommais |
// as published by the Free Software Foundation; either version 2 of // | |
// the License, or (at your option) any later version. // | Lexical VHDL Analyser. Please refer to the IEEE Standard VHDL |
// // | LRM Chapter 13 : Lexical Elements. |
// The Coriolis Project is distributed in the hope that it will be // +-----------------------------------------------------------------+
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with the Coriolis Project; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA
//
// License-Tag
// Authors-Tag
// ===================================================================
//
// This file is based on the Alliance VHDL parser written by
// L.A. Tabusse & Vuong H.N. (1992)
//
// Lexical VHDL Analyser. Please refer to the IEEE Standard VHDL LRM
// Chapter 13 : Lexical Elements.
//
// ===================================================================
//
// $Id: CParsVstScan.ll,v 1.2 2006/02/19 00:52:44 jpc Exp $
# include <string.h> # include <string.h>
@ -56,8 +34,14 @@ using namespace std;
# include "VstParserGrammar.hpp" # include "VstParserGrammar.hpp"
extern int vhdLineNumber;
extern void ClearVstIdentifiers ();
namespace Vst {
extern void ClearIdentifiers ();
extern void incVhdLineNumber ();
}
namespace { namespace {
@ -307,8 +291,8 @@ base_specifier (B|b|O|o|X|x)
return BitStringLit; return BitStringLit;
} }
\n { /* end of line */ vhdLineNumber++; } \n { /* end of line */ Vst::incVhdLineNumber(); }
\-\-.*$ { /* comment : skip them */ vhdLineNumber++; } \-\-.*$ { /* comment : skip them */ }
. { return *yytext; } . { return *yytext; }
@ -318,22 +302,26 @@ base_specifier (B|b|O|o|X|x)
int yywrap () { return 1; } int yywrap () { return 1; }
void ClearVstIdentifiers () namespace Vst {
{
identifiers.clear ();
} void ClearIdentifiers ()
{ identifiers.clear (); }
} // Vst namespace.
namespace { namespace {
char* lower ( char* str ) char* lower ( char* str )
{ {
for ( char* ptr = str; *ptr != '\0' ; ptr++ ) for ( char* ptr = str; *ptr != '\0' ; ptr++ )
*ptr = (char)tolower ( *ptr ); *ptr = (char)tolower ( *ptr );
return str; return str;
} }
} } // Anonymous namespace.