OpenSTA/liberty/LibertyParse.yy

182 lines
3.5 KiB
Plaintext

%{
// OpenSTA, Static Timing Analyzer
// Copyright (c) 2019, 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/>.
#include <stdlib.h>
#include <string.h>
#include "Machine.hh"
#include "StringUtil.hh"
#include "LibertyParser.hh"
int LibertyLex_lex();
int LibertyParse_error(const char *msg);
#define LibertyParse_lex LibertyLex_lex
// Use yacc generated parser errors.
#define YYERROR_VERBOSE
%}
%union {
char *string;
float number;
int line;
sta::LibertyAttrValue *attr_value;
sta::LibertyAttrValueSeq *attr_values;
sta::LibertyGroup *group;
sta::LibertyStmt *stmt;
}
%token <number> FLOAT
%token <string> STRING KEYWORD
%type <stmt> statement complex_attr simple_attr variable group file
%type <attr_values> attr_values
%type <attr_value> attr_value simple_attr_value
%type <string> string
%type <line> line
%type <number> volt_expr volt_token
%start file
%{
%}
%%
file:
group
;
group:
KEYWORD '(' ')' line '{'
{ sta::libertyGroupBegin($1, NULL, $4); }
'}' semi_opt
{ $$ = sta::libertyGroupEnd(); }
| KEYWORD '(' ')' line '{'
{ sta::libertyGroupBegin($1, NULL, $4); }
statements '}' semi_opt
{ $$ = sta::libertyGroupEnd(); }
| KEYWORD '(' attr_values ')' line '{'
{ sta::libertyGroupBegin($1, $3, $5); }
'}' semi_opt
{ $$ = sta::libertyGroupEnd(); }
| KEYWORD '(' attr_values ')' line '{'
{ sta::libertyGroupBegin($1, $3, $5); }
statements '}' semi_opt
{ $$ = sta::libertyGroupEnd(); }
;
line: /* empty */
{ $$ = sta::libertyLine(); }
;
statements:
statement
| statements statement
;
statement:
simple_attr
| complex_attr
| group
| variable
;
simple_attr:
KEYWORD ':' simple_attr_value line semi_opt
{ $$ = sta::makeLibertySimpleAttr($1, $3, $4); }
;
simple_attr_value:
attr_value
| volt_expr
{ $$ = static_cast<sta::LibertyAttrValue*>(NULL); }
/* Unquoted NOT function. */
/* clocked_on : !CP; */
| '!' string
{ $$ = sta::makeLibertyStringAttrValue(sta::stringPrint(strlen($2)+1, "!%s", $2)); sta::stringDelete($2); }
;
complex_attr:
KEYWORD '(' ')' line semi_opt
{ $$ = sta::makeLibertyComplexAttr($1, NULL, $4); }
| KEYWORD '(' attr_values ')' line semi_opt
{ $$ = sta::makeLibertyComplexAttr($1, $3, $5); }
;
attr_values:
attr_value
{ $$ = new sta::LibertyAttrValueSeq;
$$->push_back($1);
}
| attr_values ',' attr_value
{ $1->push_back($3);
$$ = $1;
}
| attr_values attr_value
{ $1->push_back($2);
$$ = $1;
}
;
variable:
string '=' FLOAT line semi_opt
{ $$ = sta::makeLibertyVariable($1, $3, $4); }
;
string:
STRING
{ $$ = $1; }
| KEYWORD
{ $$ = $1; }
;
attr_value:
FLOAT
{ $$ = sta::makeLibertyFloatAttrValue($1); }
| string
{ $$ = sta::makeLibertyStringAttrValue($1); }
;
/* Voltage expressions are ignored. */
volt_expr:
volt_token expr_op volt_token
| volt_expr expr_op volt_token
;
volt_token:
FLOAT
| KEYWORD
{ sta::stringDelete($1);
$$ = 0.0;
}
;
expr_op:
'+'
| '-'
| '*'
| '/'
;
semi_opt:
/* empty */
| semi_opt ';'
;
%%