mirror of
https://github.com/The-OpenROAD-Project/OpenSTA.git
synced 2026-08-29 17:28:57 +02:00
LibExpr/spef/saif c++ parsers
commit a686a6f77e555513adc40228471c1ad1af4646b3 Author: James Cherry <[email protected]> Date: Fri Jan 31 18:45:44 2025 -0800 spef compiles Signed-off-by: James Cherry <[email protected]> commit 986a3a00c246a927c494066c56bb627e55da8692 Author: James Cherry <[email protected]> Date: Fri Jan 31 18:45:32 2025 -0800 spef compiles Signed-off-by: James Cherry <[email protected]> commit e8664d21c0b404a82967201c19a087c6680b7177 Author: James Cherry <[email protected]> Date: Fri Jan 31 16:36:19 2025 -0800 saif compiles Signed-off-by: James Cherry <[email protected]> commit 496569018791bff19e57c534f29ac085520fc520 Author: James Cherry <[email protected]> Date: Fri Jan 31 15:25:44 2025 -0800 mv bison error funcs to .yy Signed-off-by: James Cherry <[email protected]> commit c1e7638840f94eb0baddee47507e607b000ab858 Author: James Cherry <[email protected]> Date: Fri Jan 31 14:19:26 2025 -0800 parser cledanup Signed-off-by: James Cherry <[email protected]> commit 22bc72af46114ddb4fc5876655887ef1189f2195 Author: James Cherry <[email protected]> Date: Fri Jan 31 14:19:06 2025 -0800 parser cleanup Signed-off-by: James Cherry <[email protected]> commit caeedc4c9e2bf8e7a2f4aceb4ee4a5758efd1b36 Author: James Cherry <[email protected]> Date: Fri Jan 31 12:52:55 2025 -0800 LibertyParser stack stream Signed-off-by: James Cherry <[email protected]> commit e029a01c2fc5ba0ed336978c5853d49095d07d66 Author: James Cherry <[email protected]> Date: Fri Jan 31 12:10:35 2025 -0800 bison 3.2 required Signed-off-by: James Cherry <[email protected]> commit 2ca9423a2d518f51fdee6c41d41348dbfd548bae Author: James Cherry <[email protected]> Date: Fri Jan 31 12:05:19 2025 -0800 LibertyExpr -> LibExpr Signed-off-by: James Cherry <[email protected]> commit d64df413675c2978c0f24d5594cc201032233447 Author: James Cherry <[email protected]> Date: Fri Jan 31 11:18:05 2025 -0800 LibertyExpr -> LibExpr Signed-off-by: James Cherry <[email protected]> commit 57cfbae240984bd7928862b1d6c3b1047ee5d71f Author: James Cherry <[email protected]> Date: Fri Jan 31 10:25:49 2025 -0800 comment Signed-off-by: James Cherry <[email protected]> commit 5249ac32d809ba30ce09437d61beaf4360bc2cd8 Author: James Cherry <[email protected]> Date: Fri Jan 31 10:24:35 2025 -0800 parseError Signed-off-by: James Cherry <[email protected]> commit 8c5442007f99c06bfb16a496e00862353c82282c Author: James Cherry <[email protected]> Date: Fri Jan 31 10:11:46 2025 -0800 libecxpr parseError unused Signed-off-by: James Cherry <[email protected]> commit 67dacf60db2c0d7e3f7ceeae672b4bdaf1e039b7 Author: James Cherry <[email protected]> Date: Fri Jan 31 10:09:39 2025 -0800 reader pvt includes Signed-off-by: James Cherry <[email protected]> commit 1d7097399b4242833bf5a478c903b5d98afe674b Author: James Cherry <[email protected]> Date: Fri Jan 31 09:33:37 2025 -0800 libexpr life Signed-off-by: James Cherry <[email protected]> commit cc85e357463399291cb1e7d7b628e5dd356ac8a9 Author: James Cherry <[email protected]> Date: Fri Jan 31 09:21:12 2025 -0800 libexpr no location Signed-off-by: James Cherry <[email protected]> commit e3ef17a746eb4e8822cce732250ae77261d53cf9 Author: James Cherry <[email protected]> Date: Thu Jan 30 22:15:50 2025 -0800 compiles Signed-off-by: James Cherry <[email protected]> commit 3a34874297a5c82930ee0bd131425bccf48526ce Author: James Cherry <[email protected]> Date: Thu Jan 30 20:03:06 2025 -0800 libexpr parse Signed-off-by: James Cherry <[email protected]> Signed-off-by: James Cherry <[email protected]>
This commit is contained in:
+81
-90
@@ -1,5 +1,4 @@
|
||||
%{
|
||||
|
||||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, Parallax Software, Inc.
|
||||
//
|
||||
@@ -31,30 +30,28 @@
|
||||
#include "StringUtil.hh"
|
||||
#include "parasitics/SpefReaderPvt.hh"
|
||||
#include "SpefParse.hh"
|
||||
#include "parasitics/SpefScanner.hh"
|
||||
|
||||
#define YY_NO_INPUT
|
||||
#undef YY_DECL
|
||||
#define YY_DECL \
|
||||
int \
|
||||
sta::SpefScanner::lex(sta::SpefParse::semantic_type *const yylval, \
|
||||
sta::SpefParse::location_type *loc)
|
||||
|
||||
static std::string spef_token;
|
||||
|
||||
void
|
||||
spefFlushBuffer()
|
||||
{
|
||||
YY_FLUSH_BUFFER;
|
||||
}
|
||||
|
||||
// Reset the start condition to INITIAL.
|
||||
void
|
||||
spefResetScanner()
|
||||
{
|
||||
BEGIN(0);
|
||||
}
|
||||
// update location on matching
|
||||
#define YY_USER_ACTION loc->step(); loc->columns(yyleng);
|
||||
|
||||
typedef sta::SpefParse::token token;
|
||||
%}
|
||||
|
||||
/* %option debug */
|
||||
%option c++
|
||||
%option yyclass="sta::SpefScanner"
|
||||
%option prefix="Spef"
|
||||
%option noyywrap
|
||||
%option nounput
|
||||
%option never-interactive
|
||||
%option stack
|
||||
%option yylineno
|
||||
/* %option debug */
|
||||
|
||||
%x COMMENT
|
||||
%x QUOTE
|
||||
@@ -93,123 +90,117 @@ INDEX "*"{POS_INTEGER}
|
||||
|
||||
%%
|
||||
|
||||
"*BUS_DELIMITER" { return BUS_DELIMITER; }
|
||||
"*C2_R1_C1" { return C2_R1_C1; }
|
||||
"*C" { return KW_C; }
|
||||
"*CAP" { return CAP; }
|
||||
"*CELL" { return CELL; }
|
||||
"*CONN" { return CONN; }
|
||||
"*C_UNIT" { return C_UNIT; }
|
||||
"*SPEF" { return SPEF; }
|
||||
"*DATE" { return DATE; }
|
||||
"*DEFINE" { return DEFINE; }
|
||||
"*DELIMITER" { return DELIMITER; }
|
||||
"*DESIGN" { return DESIGN; }
|
||||
"*DESIGN_FLOW" { return DESIGN_FLOW; }
|
||||
"*DIVIDER" { return DIVIDER; }
|
||||
"*DRIVER" { return DRIVER; }
|
||||
"*D_NET" { return D_NET; }
|
||||
"*D_PNET" { return D_PNET; }
|
||||
"*D" { return KW_D; }
|
||||
"*END" { return END; }
|
||||
"*GROUND_NETS" { return GROUND_NETS; }
|
||||
"*INDUC" { return INDUC; }
|
||||
"*I" { return KW_I; }
|
||||
"*K" { return KW_K; }
|
||||
"*L" { return KW_L; }
|
||||
"*LOADS" { return LOADS; }
|
||||
"*L_UNIT" { return L_UNIT; }
|
||||
"*NAME_MAP" { return NAME_MAP; }
|
||||
"*N" { return KW_N; }
|
||||
"*PDEFINE" { return PDEFINE; }
|
||||
"*PHYSICAL_PORTS" { return PHYSICAL_PORTS; }
|
||||
"*PORTS" { return PORTS; }
|
||||
"*POWER_NETS" { return POWER_NETS; }
|
||||
"*PROGRAM" { return PROGRAM; }
|
||||
"*P" { return KW_P; }
|
||||
"*Q" { return KW_Q; }
|
||||
"*RC" { return RC; }
|
||||
"*RES" { return RES; }
|
||||
"*R_NET" { return R_NET; }
|
||||
"*R_PNET" { return R_PNET; }
|
||||
"*R_UNIT" { return R_UNIT; }
|
||||
"*S" { return KW_S; }
|
||||
"*T_UNIT" { return T_UNIT; }
|
||||
"*VENDOR" { return VENDOR; }
|
||||
"*VERSION" { return PVERSION; }
|
||||
"*V" { return KW_V; }
|
||||
"*BUS_DELIMITER" { return token::BUS_DELIMITER; }
|
||||
"*C2_R1_C1" { return token::C2_R1_C1; }
|
||||
"*C" { return token::KW_C; }
|
||||
"*CAP" { return token::CAP; }
|
||||
"*CELL" { return token::CELL; }
|
||||
"*CONN" { return token::CONN; }
|
||||
"*C_UNIT" { return token::C_UNIT; }
|
||||
"*SPEF" { return token::SPEF; }
|
||||
"*DATE" { return token::DATE; }
|
||||
"*DEFINE" { return token::DEFINE; }
|
||||
"*DELIMITER" { return token::DELIMITER; }
|
||||
"*DESIGN" { return token::DESIGN; }
|
||||
"*DESIGN_FLOW" { return token::DESIGN_FLOW; }
|
||||
"*DIVIDER" { return token::DIVIDER; }
|
||||
"*DRIVER" { return token::DRIVER; }
|
||||
"*D_NET" { return token::D_NET; }
|
||||
"*D_PNET" { return token::D_PNET; }
|
||||
"*D" { return token::KW_D; }
|
||||
"*END" { return token::END; }
|
||||
"*GROUND_NETS" { return token::GROUND_NETS; }
|
||||
"*INDUC" { return token::INDUC; }
|
||||
"*I" { return token::KW_I; }
|
||||
"*K" { return token::KW_K; }
|
||||
"*L" { return token::KW_L; }
|
||||
"*LOADS" { return token::LOADS; }
|
||||
"*L_UNIT" { return token::L_UNIT; }
|
||||
"*NAME_MAP" { return token::NAME_MAP; }
|
||||
"*N" { return token::KW_N; }
|
||||
"*PDEFINE" { return token::PDEFINE; }
|
||||
"*PHYSICAL_PORTS" { return token::PHYSICAL_PORTS; }
|
||||
"*PORTS" { return token::PORTS; }
|
||||
"*POWER_NETS" { return token::POWER_NETS; }
|
||||
"*PROGRAM" { return token::PROGRAM; }
|
||||
"*P" { return token::KW_P; }
|
||||
"*Q" { return token::KW_Q; }
|
||||
"*RC" { return token::RC; }
|
||||
"*RES" { return token::RES; }
|
||||
"*R_NET" { return token::R_NET; }
|
||||
"*R_PNET" { return token::R_PNET; }
|
||||
"*R_UNIT" { return token::R_UNIT; }
|
||||
"*S" { return token::KW_S; }
|
||||
"*T_UNIT" { return token::T_UNIT; }
|
||||
"*VENDOR" { return token::VENDOR; }
|
||||
"*VERSION" { return token::PVERSION; }
|
||||
"*V" { return token::KW_V; }
|
||||
|
||||
"//".*\n { /* Single line comment */
|
||||
sta::spef_reader->incrLine();
|
||||
}
|
||||
"//".*\n { loc->lines(); loc->step(); } /* Single line comment */
|
||||
|
||||
"/*" { BEGIN COMMENT; }
|
||||
<COMMENT>{
|
||||
|
||||
.
|
||||
|
||||
\n { sta::spef_reader->incrLine(); }
|
||||
\n { loc->lines(); loc->step(); }
|
||||
|
||||
"*/" { BEGIN INITIAL; }
|
||||
|
||||
<<EOF>> {
|
||||
SpefParse_error("unterminated comment");
|
||||
error("unterminated comment");
|
||||
BEGIN(INITIAL);
|
||||
yyterminate();
|
||||
}
|
||||
}
|
||||
|
||||
"\"" { BEGIN QUOTE; spef_token.erase(); }
|
||||
"\"" { BEGIN QUOTE; token_.erase(); }
|
||||
<QUOTE>{
|
||||
|
||||
\r?\n {
|
||||
sta::spef_reader->incrLine();
|
||||
}
|
||||
\r?\n { loc->lines(); loc->step(); }
|
||||
|
||||
"\\". { spef_token += yytext[1]; }
|
||||
"\\". { token_ += yytext[1]; }
|
||||
|
||||
"\"" {
|
||||
BEGIN INITIAL;
|
||||
SpefParse_lval.string = sta::stringCopy(spef_token.c_str());
|
||||
return QSTRING;
|
||||
yylval->string = sta::stringCopy(token_.c_str());
|
||||
return token::QSTRING;
|
||||
}
|
||||
|
||||
. { spef_token += yytext[0]; }
|
||||
. { token_ += yytext[0]; }
|
||||
|
||||
<<EOF>> {
|
||||
SpefParse_error("unterminated quoted string");
|
||||
error("unterminated quoted string");
|
||||
BEGIN(INITIAL);
|
||||
yyterminate();
|
||||
}
|
||||
}
|
||||
|
||||
{BLANK}*\n {
|
||||
sta::spef_reader->incrLine();
|
||||
}
|
||||
{BLANK}*\n { loc->lines(); loc->step(); }
|
||||
|
||||
{INTEGER} {
|
||||
SpefParse_lval.integer = atoi(yytext);
|
||||
return INTEGER;
|
||||
yylval->integer = atoi(yytext);
|
||||
return token::INTEGER;
|
||||
}
|
||||
|
||||
{FLOAT} {
|
||||
SpefParse_lval.number = static_cast<float>(atof(yytext));
|
||||
return FLOAT;
|
||||
yylval->number = static_cast<float>(atof(yytext));
|
||||
return token::FLOAT;
|
||||
}
|
||||
|
||||
{IDENT} {
|
||||
SpefParse_lval.string = sta::spef_reader->translated(yytext);
|
||||
return IDENT;
|
||||
yylval->string = reader_->translated(yytext);
|
||||
return token::IDENT;
|
||||
}
|
||||
|
||||
{PATH}|{NAME_PAIR} {
|
||||
SpefParse_lval.string = sta::spef_reader->translated(yytext);
|
||||
return NAME;
|
||||
yylval->string = reader_->translated(yytext);
|
||||
return token::NAME;
|
||||
}
|
||||
|
||||
{INDEX} {
|
||||
SpefParse_lval.string = sta::stringCopy(yytext);
|
||||
return INDEX;
|
||||
yylval->string = sta::stringCopy(yytext);
|
||||
return token::INDEX;
|
||||
}
|
||||
|
||||
{HCHAR} {
|
||||
|
||||
+53
-33
@@ -1,5 +1,3 @@
|
||||
%{
|
||||
|
||||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, Parallax Software, Inc.
|
||||
//
|
||||
@@ -24,19 +22,41 @@
|
||||
//
|
||||
// This notice may not be removed or altered from any source distribution.
|
||||
|
||||
%{
|
||||
#include <cstring>
|
||||
|
||||
#include "Report.hh"
|
||||
#include "StringUtil.hh"
|
||||
#include "StringSeq.hh"
|
||||
#include "parasitics/SpefReaderPvt.hh"
|
||||
#include "parasitics/SpefScanner.hh"
|
||||
|
||||
int SpefLex_lex();
|
||||
#define SpefParse_lex SpefLex_lex
|
||||
// use yacc generated parser errors
|
||||
#define YYERROR_VERBOSE
|
||||
#undef yylex
|
||||
#define yylex scanner->lex
|
||||
|
||||
// warning: variable 'yynerrs_' set but not used
|
||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||
|
||||
void
|
||||
sta::SpefParse::error(const location_type &loc,
|
||||
const string &msg)
|
||||
{
|
||||
reader->report()->fileError(164,reader->filename(),
|
||||
loc.begin.line,"%s",msg.c_str());
|
||||
}
|
||||
%}
|
||||
|
||||
%require "3.2"
|
||||
%skeleton "lalr1.cc"
|
||||
%debug
|
||||
%define api.namespace {sta}
|
||||
%locations
|
||||
%define api.location.file "SpefLocation.hh"
|
||||
%define parse.assert
|
||||
%parse-param { SpefScanner *scanner }
|
||||
%parse-param { SpefReader *reader }
|
||||
%define api.parser.class {SpefParse}
|
||||
|
||||
%union {
|
||||
char ch;
|
||||
char *string;
|
||||
@@ -195,7 +215,7 @@ vendor:
|
||||
|
||||
design_flow:
|
||||
DESIGN_FLOW qstrings
|
||||
{ sta::spef_reader->setDesignFlow($2); }
|
||||
{ reader->setDesignFlow($2); }
|
||||
;
|
||||
|
||||
qstrings:
|
||||
@@ -209,19 +229,19 @@ qstrings:
|
||||
|
||||
hierarchy_div_def:
|
||||
DIVIDER hchar
|
||||
{ sta::spef_reader->setDivider($2); }
|
||||
{ reader->setDivider($2); }
|
||||
;
|
||||
|
||||
pin_delim_def:
|
||||
DELIMITER hchar
|
||||
{ sta::spef_reader->setDelimiter($2); }
|
||||
{ reader->setDelimiter($2); }
|
||||
;
|
||||
|
||||
bus_delim_def:
|
||||
BUS_DELIMITER prefix_bus_delim
|
||||
{ sta::spef_reader->setBusBrackets($2, '\0'); }
|
||||
{ reader->setBusBrackets($2, '\0'); }
|
||||
| BUS_DELIMITER prefix_bus_delim suffix_bus_delim
|
||||
{ sta::spef_reader->setBusBrackets($2, $3); }
|
||||
{ reader->setBusBrackets($2, $3); }
|
||||
;
|
||||
|
||||
/****************************************************************/
|
||||
@@ -235,22 +255,22 @@ unit_def:
|
||||
|
||||
time_scale:
|
||||
T_UNIT pos_number IDENT
|
||||
{ sta::spef_reader->setTimeScale($2, $3); }
|
||||
{ reader->setTimeScale($2, $3); }
|
||||
;
|
||||
|
||||
cap_scale:
|
||||
C_UNIT pos_number IDENT
|
||||
{ sta::spef_reader->setCapScale($2, $3); }
|
||||
{ reader->setCapScale($2, $3); }
|
||||
;
|
||||
|
||||
res_scale:
|
||||
R_UNIT pos_number IDENT
|
||||
{ sta::spef_reader->setResScale($2, $3); }
|
||||
{ reader->setResScale($2, $3); }
|
||||
;
|
||||
|
||||
induc_scale:
|
||||
L_UNIT pos_number IDENT
|
||||
{ sta::spef_reader->setInductScale($2, $3); }
|
||||
{ reader->setInductScale($2, $3); }
|
||||
;
|
||||
|
||||
/****************************************************************/
|
||||
@@ -267,7 +287,7 @@ name_map_entries:
|
||||
|
||||
name_map_entry:
|
||||
INDEX mapped_item
|
||||
{ sta::spef_reader->makeNameMapEntry($1, $2);
|
||||
{ reader->makeNameMapEntry($1, $2);
|
||||
sta::stringDelete($1);
|
||||
}
|
||||
;
|
||||
@@ -330,7 +350,7 @@ port_entry:
|
||||
|
||||
direction:
|
||||
IDENT
|
||||
{ $$ = sta::spef_reader->portDirection($1);
|
||||
{ $$ = reader->portDirection($1);
|
||||
sta::stringDelete($1);
|
||||
}
|
||||
;
|
||||
@@ -474,14 +494,14 @@ nets:
|
||||
|
||||
d_net:
|
||||
D_NET net total_cap
|
||||
{ sta::spef_reader->dspfBegin($2, $3); }
|
||||
{ reader->dspfBegin($2, $3); }
|
||||
routing_conf conn_sec cap_sec res_sec induc_sec END
|
||||
{ sta::spef_reader->dspfFinish(); }
|
||||
{ reader->dspfFinish(); }
|
||||
;
|
||||
|
||||
net:
|
||||
name_or_index
|
||||
{ $$ = sta::spef_reader->findNet($1);
|
||||
{ $$ = reader->findNet($1);
|
||||
sta::stringDelete($1);
|
||||
}
|
||||
;
|
||||
@@ -531,7 +551,7 @@ internal_connection:
|
||||
|
||||
pin_name:
|
||||
name_or_index
|
||||
{ $$ = sta::spef_reader->findPin($1);
|
||||
{ $$ = reader->findPin($1);
|
||||
sta::stringDelete($1);
|
||||
}
|
||||
;
|
||||
@@ -565,9 +585,9 @@ cap_elems:
|
||||
|
||||
cap_elem:
|
||||
cap_id parasitic_node par_value
|
||||
{ sta::spef_reader->makeCapacitor($1, $2, $3); }
|
||||
{ reader->makeCapacitor($1, $2, $3); }
|
||||
| cap_id parasitic_node parasitic_node par_value
|
||||
{ sta::spef_reader->makeCapacitor($1, $2, $3, $4); }
|
||||
{ reader->makeCapacitor($1, $2, $3, $4); }
|
||||
;
|
||||
|
||||
cap_id:
|
||||
@@ -593,7 +613,7 @@ res_elems:
|
||||
|
||||
res_elem:
|
||||
res_id parasitic_node parasitic_node par_value
|
||||
{ sta::spef_reader->makeResistor($1, $2, $3, $4); }
|
||||
{ reader->makeResistor($1, $2, $3, $4); }
|
||||
;
|
||||
|
||||
res_id:
|
||||
@@ -626,9 +646,9 @@ induc_id:
|
||||
|
||||
r_net:
|
||||
R_NET net total_cap
|
||||
{ sta::spef_reader->rspfBegin($2, $3); }
|
||||
{ reader->rspfBegin($2, $3); }
|
||||
routing_conf driver_reducs END
|
||||
{ sta::spef_reader->rspfFinish(); }
|
||||
{ reader->rspfFinish(); }
|
||||
;
|
||||
|
||||
driver_reducs:
|
||||
@@ -638,11 +658,11 @@ driver_reducs:
|
||||
|
||||
driver_reduc:
|
||||
driver_pair driver_cell pi_model
|
||||
{ sta::spef_reader->rspfDrvrBegin($1, $3);
|
||||
{ reader->rspfDrvrBegin($1, $3);
|
||||
sta::stringDelete($2);
|
||||
}
|
||||
load_desc
|
||||
{ sta::spef_reader->rspfDrvrFinish(); }
|
||||
{ reader->rspfDrvrFinish(); }
|
||||
;
|
||||
|
||||
driver_pair:
|
||||
@@ -673,9 +693,9 @@ rc_descs:
|
||||
|
||||
rc_desc:
|
||||
RC pin_name par_value
|
||||
{ sta::spef_reader->rspfLoad($2, $3); }
|
||||
{ reader->rspfLoad($2, $3); }
|
||||
| RC pin_name par_value pole_residue_desc
|
||||
{ sta::spef_reader->rspfLoad($2, $3); }
|
||||
{ reader->rspfLoad($2, $3); }
|
||||
;
|
||||
|
||||
pole_residue_desc:
|
||||
@@ -810,7 +830,7 @@ pos_integer:
|
||||
INTEGER
|
||||
{ int value = $1;
|
||||
if (value < 0)
|
||||
sta::spef_reader->warn(1525, "%d is not positive.", value);
|
||||
reader->warn(1525, "%d is not positive.", value);
|
||||
$$ = value;
|
||||
}
|
||||
;
|
||||
@@ -819,13 +839,13 @@ pos_number:
|
||||
INTEGER
|
||||
{ float value = static_cast<float>($1);
|
||||
if (value < 0)
|
||||
sta::spef_reader->warn(1526, "%.4f is not positive.", value);
|
||||
reader->warn(1526, "%.4f is not positive.", value);
|
||||
$$ = value;
|
||||
}
|
||||
| FLOAT
|
||||
{ float value = static_cast<float>($1);
|
||||
if (value < 0)
|
||||
sta::spef_reader->warn(1527, "%.4f is not positive.", value);
|
||||
reader->warn(1527, "%.4f is not positive.", value);
|
||||
$$ = value;
|
||||
}
|
||||
;
|
||||
|
||||
+43
-77
@@ -40,17 +40,10 @@
|
||||
#include "ArcDelayCalc.hh"
|
||||
#include "SpefReaderPvt.hh"
|
||||
#include "SpefNamespace.hh"
|
||||
|
||||
int
|
||||
SpefParse_parse();
|
||||
void
|
||||
spefResetScanner();
|
||||
#include "parasitics/SpefScanner.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
// Referenced by parser.
|
||||
SpefReader *spef_reader;
|
||||
|
||||
bool
|
||||
readSpefFile(const char *filename,
|
||||
Instance *instance,
|
||||
@@ -63,35 +56,14 @@ readSpefFile(const char *filename,
|
||||
const MinMaxAll *min_max,
|
||||
StaState *sta)
|
||||
{
|
||||
bool success = false;
|
||||
const ArcDelayCalc *arc_delay_calc = sta->arcDelayCalc();
|
||||
if (reduce && !arc_delay_calc->reduceSupported()) {
|
||||
sta->report()->warn(1658, "Delay calculator %s does not support reduction.",
|
||||
arc_delay_calc->name());
|
||||
reduce = false;
|
||||
}
|
||||
// Use zlib to uncompress gzip'd files automagically.
|
||||
gzFile stream = gzopen(filename, "rb");
|
||||
if (stream) {
|
||||
Stats stats(sta->debug(), sta->report());
|
||||
SpefReader reader(filename, stream, instance, ap,
|
||||
pin_cap_included, keep_coupling_caps, coupling_cap_factor,
|
||||
reduce, corner, min_max, sta);
|
||||
spef_reader = &reader;
|
||||
::spefResetScanner();
|
||||
// yyparse returns 0 on success.
|
||||
success = (::SpefParse_parse() == 0);
|
||||
gzclose(stream);
|
||||
spef_reader = nullptr;
|
||||
stats.report("Read spef");
|
||||
}
|
||||
else
|
||||
throw FileNotReadable(filename);
|
||||
SpefReader reader(filename, instance, ap,
|
||||
pin_cap_included, keep_coupling_caps, coupling_cap_factor,
|
||||
reduce, corner, min_max, sta);
|
||||
bool success = reader.read();
|
||||
return success;
|
||||
}
|
||||
|
||||
SpefReader::SpefReader(const char *filename,
|
||||
gzFile stream,
|
||||
Instance *instance,
|
||||
ParasiticAnalysisPt *ap,
|
||||
bool pin_cap_included,
|
||||
@@ -110,8 +82,6 @@ SpefReader::SpefReader(const char *filename,
|
||||
reduce_(reduce),
|
||||
corner_(corner),
|
||||
min_max_(min_max),
|
||||
stream_(stream),
|
||||
line_(1),
|
||||
// defaults
|
||||
divider_('\0'),
|
||||
delimiter_('\0'),
|
||||
@@ -141,6 +111,25 @@ SpefReader::~SpefReader()
|
||||
stringDelete(name);
|
||||
}
|
||||
|
||||
bool
|
||||
SpefReader::read()
|
||||
{
|
||||
bool success;
|
||||
gzstream::igzstream stream(filename_);
|
||||
if (stream.is_open()) {
|
||||
Stats stats(debug_, report_);
|
||||
SpefScanner scanner(&stream, filename_, this, report_);
|
||||
scanner_ = &scanner;
|
||||
SpefParse parser(&scanner, this);
|
||||
// yyparse returns 0 on success.
|
||||
success = (parser.parse() == 0);
|
||||
stats.report("Read spef");
|
||||
}
|
||||
else
|
||||
throw FileNotReadable(filename_);
|
||||
return success;
|
||||
}
|
||||
|
||||
void
|
||||
SpefReader::setDivider(char divider)
|
||||
{
|
||||
@@ -154,7 +143,8 @@ SpefReader::setDelimiter(char delimiter)
|
||||
}
|
||||
|
||||
void
|
||||
SpefReader::setBusBrackets(char left, char right)
|
||||
SpefReader::setBusBrackets(char left,
|
||||
char right)
|
||||
{
|
||||
if (!((left == '[' && right == ']')
|
||||
|| (left == '{' && right == '}')
|
||||
@@ -196,30 +186,6 @@ SpefReader::findPortPinRelative(const char *name)
|
||||
return network_->findPin(instance_, name);
|
||||
}
|
||||
|
||||
void
|
||||
SpefReader::getChars(char *buf,
|
||||
int &result,
|
||||
size_t max_size)
|
||||
{
|
||||
char *status = gzgets(stream_, buf, max_size);
|
||||
if (status == Z_NULL)
|
||||
result = 0; // YY_nullptr
|
||||
else
|
||||
result = static_cast<int>(strlen(buf));
|
||||
}
|
||||
|
||||
void
|
||||
SpefReader::getChars(char *buf,
|
||||
size_t &result,
|
||||
size_t max_size)
|
||||
{
|
||||
char *status = gzgets(stream_, buf, max_size);
|
||||
if (status == Z_NULL)
|
||||
result = 0; // YY_nullptr
|
||||
else
|
||||
result = strlen(buf);
|
||||
}
|
||||
|
||||
char *
|
||||
SpefReader::translated(const char *token)
|
||||
{
|
||||
@@ -227,18 +193,12 @@ SpefReader::translated(const char *token)
|
||||
network_->pathEscape());
|
||||
}
|
||||
|
||||
void
|
||||
SpefReader::incrLine()
|
||||
{
|
||||
line_++;
|
||||
}
|
||||
|
||||
void
|
||||
SpefReader::warn(int id, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
report_->vfileWarn(id, filename_, line_, fmt, args);
|
||||
report_->vfileWarn(id, filename_, scanner_->line(), fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
@@ -644,17 +604,23 @@ SpefTriple::value(int index) const
|
||||
return values_[0];
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Global namespace
|
||||
|
||||
void spefFlushBuffer();
|
||||
|
||||
int
|
||||
SpefParse_error(const char *msg)
|
||||
SpefScanner::SpefScanner(std::istream *stream,
|
||||
const string &filename,
|
||||
SpefReader *reader,
|
||||
Report *report) :
|
||||
yyFlexLexer(stream),
|
||||
filename_(filename),
|
||||
reader_(reader),
|
||||
report_(report)
|
||||
{
|
||||
spefFlushBuffer();
|
||||
sta::spef_reader->warn(1657, "%s.", msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
SpefScanner::error(const char *msg)
|
||||
{
|
||||
report_->fileError(1866, filename_.c_str(), lineno(), "%s", msg);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -32,15 +32,6 @@
|
||||
#include "ParasiticsClass.hh"
|
||||
#include "StaState.hh"
|
||||
|
||||
// Global namespace.
|
||||
#define YY_INPUT(buf,result,max_size) \
|
||||
sta::spef_reader->getChars(buf, result, max_size)
|
||||
|
||||
int
|
||||
SpefParse_error(const char *msg);
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace sta {
|
||||
|
||||
class Report;
|
||||
@@ -48,6 +39,7 @@ class MinMaxAll;
|
||||
class SpefRspfPi;
|
||||
class SpefTriple;
|
||||
class Corner;
|
||||
class SpefScanner;
|
||||
|
||||
typedef std::map<int, char*, std::less<int>> SpefNameMap;
|
||||
|
||||
@@ -55,7 +47,6 @@ class SpefReader : public StaState
|
||||
{
|
||||
public:
|
||||
SpefReader(const char *filename,
|
||||
gzFile stream,
|
||||
Instance *instance,
|
||||
ParasiticAnalysisPt *ap,
|
||||
bool pin_cap_included,
|
||||
@@ -66,21 +57,12 @@ public:
|
||||
const MinMaxAll *min_max,
|
||||
StaState *sta);
|
||||
virtual ~SpefReader();
|
||||
bool read();
|
||||
char divider() const { return divider_; }
|
||||
void setDivider(char divider);
|
||||
char delimiter() const { return delimiter_; }
|
||||
void setDelimiter(char delimiter);
|
||||
void incrLine();
|
||||
int line() const { return line_; }
|
||||
const char *filename() const { return filename_; }
|
||||
// flex YY_INPUT yy_n_chars arg changed definition from int to size_t,
|
||||
// so provide both forms.
|
||||
void getChars(char *buf,
|
||||
int &result,
|
||||
size_t max_size);
|
||||
void getChars(char *buf,
|
||||
size_t &result,
|
||||
size_t max_size);
|
||||
// Translate from spf/spef namespace to sta namespace.
|
||||
char *translated(const char *token);
|
||||
void warn(int id,
|
||||
@@ -136,6 +118,7 @@ private:
|
||||
bool local_only);
|
||||
|
||||
const char *filename_;
|
||||
SpefScanner *scanner_;
|
||||
Instance *instance_;
|
||||
const ParasiticAnalysisPt *ap_;
|
||||
bool pin_cap_included_;
|
||||
@@ -144,8 +127,6 @@ private:
|
||||
const Corner *corner_;
|
||||
const MinMaxAll *min_max_;
|
||||
// Normally no need to keep device names.
|
||||
gzFile stream_;
|
||||
int line_;
|
||||
char divider_;
|
||||
char delimiter_;
|
||||
char bus_brkt_left_;
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2025, Parallax Software, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
// The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software.
|
||||
//
|
||||
// Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
//
|
||||
// This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SpefLocation.hh"
|
||||
#include "SpefParse.hh"
|
||||
|
||||
#ifndef __FLEX_LEXER_H
|
||||
#undef yyFlexLexer
|
||||
#define yyFlexLexer SpefFlexLexer
|
||||
#include <FlexLexer.h>
|
||||
#endif
|
||||
|
||||
namespace sta {
|
||||
|
||||
class Report;
|
||||
|
||||
class SpefScanner : public SpefFlexLexer
|
||||
{
|
||||
public:
|
||||
SpefScanner(std::istream *stream,
|
||||
const string &filename,
|
||||
SpefReader *reader,
|
||||
Report *report);
|
||||
virtual ~SpefScanner() {}
|
||||
|
||||
virtual int lex(SpefParse::semantic_type *const yylval,
|
||||
SpefParse::location_type *yylloc);
|
||||
// YY_DECL defined in SpefLex.ll
|
||||
// Method body created by flex in SpefLex.cc
|
||||
|
||||
void error(const char *msg);
|
||||
int line() const { return yylineno; }
|
||||
|
||||
// Get rid of override virtual function warning.
|
||||
using FlexLexer::yylex;
|
||||
|
||||
private:
|
||||
string filename_;
|
||||
SpefReader *reader_;
|
||||
Report *report_;
|
||||
string token_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user