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_; }