diff --git a/CMakeLists.txt b/CMakeLists.txt
index af438059..8f713ec5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -256,7 +256,7 @@ flex_target(LibertyLex ${STA_HOME}/liberty/LibertyLex.ll ${CMAKE_CURRENT_BINARY_
COMPILE_FLAGS --prefix=LibertyLex_
)
bison_target(LibertyParser ${STA_HOME}/liberty/LibertyParse.yy ${CMAKE_CURRENT_BINARY_DIR}/LibertyParse.cc
- COMPILE_FLAGS --name-prefix=LibertyParse_
+ COMPILE_FLAGS "--name-prefix=LibertyParse_ -v"
)
add_flex_bison_dependency(LibertyLex LibertyParser)
diff --git a/liberty/LibertyParse.yy b/liberty/LibertyParse.yy
index 2ac53a9d..e4177ae5 100644
--- a/liberty/LibertyParse.yy
+++ b/liberty/LibertyParse.yy
@@ -14,7 +14,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-
+
#include
#include
@@ -26,27 +26,35 @@ int LibertyLex_lex();
// Use yacc generated parser errors.
#define YYERROR_VERBOSE
+#define YYDEBUG 1
+
%}
%union {
char *string;
float number;
int line;
+ char ch;
sta::LibertyAttrValue *attr_value;
sta::LibertyAttrValueSeq *attr_values;
sta::LibertyGroup *group;
sta::LibertyStmt *stmt;
}
+%left '+' '|'
+%left '*' '&'
+%left '^'
+%left '!'
+
%token FLOAT
%token STRING KEYWORD
%type statement complex_attr simple_attr variable group file
%type attr_values
-%type attr_value simple_attr_value
-%type string
+%type attr_value
+%type string expr expr_term expr_term1 volt_expr
%type line
-%type volt_expr volt_token
+%type expr_op volt_op
%start file
@@ -61,11 +69,11 @@ file:
group:
KEYWORD '(' ')' line '{'
- { sta::libertyGroupBegin($1, NULL, $4); }
+ { sta::libertyGroupBegin($1, nullptr, $4); }
'}' semi_opt
{ $$ = sta::libertyGroupEnd(); }
| KEYWORD '(' ')' line '{'
- { sta::libertyGroupBegin($1, NULL, $4); }
+ { sta::libertyGroupBegin($1, nullptr, $4); }
statements '}' semi_opt
{ $$ = sta::libertyGroupEnd(); }
| KEYWORD '(' attr_values ')' line '{'
@@ -95,23 +103,13 @@ statement:
;
simple_attr:
- KEYWORD ':' simple_attr_value line semi_opt
+ KEYWORD ':' attr_value line semi_opt
{ $$ = sta::makeLibertySimpleAttr($1, $3, $4); }
;
-simple_attr_value:
- attr_value
-| volt_expr
- { $$ = static_cast(NULL); }
-/* Unquoted NOT function. */
-/* clocked_on : !CP; */
-| '!' string
- { $$ = sta::makeLibertyStringAttrValue(sta::stringPrint("!%s", $2)); sta::stringDelete($2); }
- ;
-
complex_attr:
KEYWORD '(' ')' line semi_opt
- { $$ = sta::makeLibertyComplexAttr($1, NULL, $4); }
+ { $$ = sta::makeLibertyComplexAttr($1, nullptr, $4); }
| KEYWORD '(' attr_values ')' line semi_opt
{ $$ = sta::makeLibertyComplexAttr($1, $3, $5); }
;
@@ -146,29 +144,86 @@ string:
attr_value:
FLOAT
{ $$ = sta::makeLibertyFloatAttrValue($1); }
- | string
+| expr
+ { $$ = sta::makeLibertyStringAttrValue($1); }
+| volt_expr
{ $$ = sta::makeLibertyStringAttrValue($1); }
;
/* Voltage expressions are ignored. */
+/* Crafted to avoid conflicts with expr */
volt_expr:
- volt_token expr_op volt_token
-| volt_expr expr_op volt_token
+ FLOAT volt_op FLOAT
+ { $$ = sta::stringPrint("%e%c%e", $1, $2, $3); }
+| string volt_op FLOAT
+ { $$ = sta::stringPrint("%s%c%e", $1, $2, $3);
+ sta::stringDelete($1);
+ }
+| FLOAT volt_op string
+ { $$ = sta::stringPrint("%e%c%s", $1, $2, $3);
+ sta::stringDelete($3);
+ }
+| volt_expr volt_op FLOAT
+ { $$ = sta::stringPrint("%s%c%e", $1, $2, $3);
+ sta::stringDelete($1);
+ }
+ ;
+
+volt_op:
+ '+'
+ { $$ = '+'; }
+| '-'
+ { $$ = '-'; }
+| '*'
+ { $$ = '*'; }
+| '/'
+ { $$ = '/'; }
;
-volt_token:
- FLOAT
-| KEYWORD
- { sta::stringDelete($1);
- $$ = 0.0;
- }
+expr:
+ expr_term1
+| expr_term1 expr_op expr
+ { $$ = sta::stringPrint("%s%c%s", $1, $2, $3);
+ sta::stringDelete($1);
+ sta::stringDelete($3);
+ }
+ ;
+
+expr_term:
+ string
+| '0'
+ { $$ = sta::stringPrint("0"); }
+| '1'
+ { $$ = sta::stringPrint("1"); }
+| '(' expr ')'
+ { $$ = sta::stringPrint("(%s)", $2);
+ sta::stringDelete($2);
+ }
+ ;
+
+expr_term1:
+ expr_term
+| '!' expr_term
+ { $$ = sta::stringPrint("!%s", $2);
+ sta::stringDelete($2);
+ }
+| expr_term '\''
+ { $$ = sta::stringPrint("%s'", $1);
+ sta::stringDelete($1);
+ }
;
expr_op:
'+'
-| '-'
+ { $$ = '+'; }
+| '|'
+ { $$ = '|'; }
| '*'
-| '/'
+ { $$ = '*'; }
+| '&'
+ { $$ = '&'; }
+| '^'
+ { $$ = '^'; }
;
semi_opt:
diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc
index 42d94c04..85cc353f 100644
--- a/liberty/LibertyReader.cc
+++ b/liberty/LibertyReader.cc
@@ -40,6 +40,8 @@
#include "ParseBus.hh"
#include "Network.hh"
+extern int LibertyParse_debug;
+
namespace sta {
static void
@@ -138,6 +140,7 @@ LibertyReader::readLibertyFile(const char *filename,
have_slew_upper_threshold_[rf_index] = false;
}
+ //::LibertyParse_debug = 1;
parseLibertyFile(filename, this, report_);
return library_;
}