blob: b390d67c4c51e11bae70863a362ec8ab24ecaf0a [file] [log] [blame] [edit]
%{
#include <stdio.h>
#include "assert.h"
#include "sdc_common.h"
int yyerror(const char *msg);
extern int yylex(void);
%}
%union {
char* strVal;
double floatVal;
int intVal;
t_sdc_commands* sdc_commands;
t_sdc_create_clock* create_clock;
t_sdc_set_io_delay* set_io_delay;
t_sdc_set_clock_groups* set_clock_groups;
t_sdc_set_false_path* set_false_path;
t_sdc_set_max_delay* set_max_delay;
t_sdc_set_multicycle_path* set_multicycle_path;
t_sdc_string_group* string_group;
}
/* Verbose error reporting */
%error-verbose
/* declare constant */
%token CMD_CREATE_CLOCK
%token CMD_SET_CLOCK_GROUPS
%token CMD_SET_FALSE_PATH
%token CMD_SET_MAX_DELAY
%token CMD_SET_MULTICYCLE_PATH
%token CMD_SET_INPUT_DELAY
%token CMD_SET_OUTPUT_DELAY
%token CMD_GET_PORTS
%token CMD_GET_CLOCKS
%token ARG_PERIOD
%token ARG_WAVEFORM
%token ARG_NAME
%token ARG_EXCLUSIVE
%token ARG_GROUP
%token ARG_FROM
%token ARG_TO
%token ARG_SETUP
%token ARG_CLOCK
%token ARG_MAX
%token EOL
/* declare variable tokens */
%token <strVal> STRING
%token <strVal> ESCAPED_STRING
%token <strVal> CHAR
%token <floatVal> FLOAT_NUMBER
%token <intVal> INT_NUMBER
/* declare types */
%type <strVal> string
%type <floatVal> number
%type <floatVal> float_number
%type <intVal> int_number
%type <sdc_commands> sdc_commands
%type <create_clock> cmd_create_clock
%type <set_io_delay> cmd_set_input_delay cmd_set_output_delay
%type <set_clock_groups> cmd_set_clock_groups
%type <set_false_path> cmd_set_false_path
%type <set_max_delay> cmd_set_max_delay
%type <set_multicycle_path> cmd_set_multicycle_path
%type <string_group> stringGroup cmd_get_ports cmd_get_clocks
/* Top level rule */
%start sdc_commands
%%
sdc_commands: { g_sdc_commands = alloc_sdc_commands(); $$ = g_sdc_commands; }
| sdc_commands cmd_create_clock EOL { $$ = add_sdc_create_clock($1, $2); }
| sdc_commands cmd_set_input_delay EOL { $$ = add_sdc_set_io_delay($1, $2); }
| sdc_commands cmd_set_output_delay EOL { $$ = add_sdc_set_io_delay($1, $2); }
| sdc_commands cmd_set_clock_groups EOL { $$ = add_sdc_set_clock_groups($1, $2); }
| sdc_commands cmd_set_false_path EOL { $$ = add_sdc_set_false_path($1, $2); }
| sdc_commands cmd_set_max_delay EOL { $$ = add_sdc_set_max_delay($1, $2); }
| sdc_commands cmd_set_multicycle_path EOL { $$ = add_sdc_set_multicycle_path($1, $2); }
| sdc_commands EOL { /* Eat stray EOL symbols */ $$ = $1; }
;
cmd_create_clock: CMD_CREATE_CLOCK { $$ = alloc_sdc_create_clock(); }
| cmd_create_clock ARG_PERIOD number { $$ = sdc_create_clock_set_period($1, $3); }
| cmd_create_clock ARG_NAME string { $$ = sdc_create_clock_set_name($1, $3); free($3); }
| cmd_create_clock ARG_WAVEFORM '{' number number '}' { $$ = sdc_create_clock_set_waveform($1, $4, $5); }
| cmd_create_clock '{' stringGroup '}' { $$ = sdc_create_clock_add_targets($1, $3); free_sdc_string_group($3); }
| cmd_create_clock string { $$ = sdc_create_clock_add_targets($1, make_sdc_string_group(SDC_STRING, $2)); free($2); }
;
cmd_set_input_delay: CMD_SET_INPUT_DELAY { $$ = alloc_sdc_set_io_delay(SDC_INPUT_DELAY); }
| cmd_set_input_delay ARG_CLOCK string { $$ = sdc_set_io_delay_set_clock($1, $3); free($3); }
| cmd_set_input_delay ARG_MAX number { $$ = sdc_set_io_delay_set_max_value($1, $3); }
| cmd_set_input_delay '[' cmd_get_ports ']' { $$ = sdc_set_io_delay_set_ports($1, $3); free_sdc_string_group($3); }
;
cmd_set_output_delay: CMD_SET_OUTPUT_DELAY { $$ = alloc_sdc_set_io_delay(SDC_OUTPUT_DELAY); }
| cmd_set_output_delay ARG_CLOCK string { $$ = sdc_set_io_delay_set_clock($1, $3); free($3); }
| cmd_set_output_delay ARG_MAX number { $$ = sdc_set_io_delay_set_max_value($1, $3); }
| cmd_set_output_delay '[' cmd_get_ports ']' { $$ = sdc_set_io_delay_set_ports($1, $3); free_sdc_string_group($3); }
;
cmd_set_clock_groups: CMD_SET_CLOCK_GROUPS { $$ = alloc_sdc_set_clock_groups(); }
| cmd_set_clock_groups ARG_EXCLUSIVE { $$ = sdc_set_clock_groups_set_type($1, SDC_CG_EXCLUSIVE); }
| cmd_set_clock_groups ARG_GROUP '[' cmd_get_clocks ']' { $$ = sdc_set_clock_groups_add_group($1, $4); free_sdc_string_group($4); }
| cmd_set_clock_groups ARG_GROUP '{' stringGroup '}' { $$ = sdc_set_clock_groups_add_group($1, $4); free_sdc_string_group($4);}
| cmd_set_clock_groups ARG_GROUP string { $$ = sdc_set_clock_groups_add_group($1, make_sdc_string_group(SDC_STRING, $3)); free($3); }
;
cmd_set_false_path: CMD_SET_FALSE_PATH { $$ = alloc_sdc_set_false_path(); }
| cmd_set_false_path ARG_FROM '[' cmd_get_clocks ']' { $$ = sdc_set_false_path_add_to_from_group($1, $4, SDC_FROM); free_sdc_string_group($4); }
| cmd_set_false_path ARG_TO '[' cmd_get_clocks ']' { $$ = sdc_set_false_path_add_to_from_group($1, $4, SDC_TO ); free_sdc_string_group($4); }
| cmd_set_false_path ARG_FROM '{' stringGroup '}' { $$ = sdc_set_false_path_add_to_from_group($1, $4, SDC_FROM); free_sdc_string_group($4); }
| cmd_set_false_path ARG_TO '{' stringGroup '}' { $$ = sdc_set_false_path_add_to_from_group($1, $4, SDC_TO ); free_sdc_string_group($4); }
| cmd_set_false_path ARG_FROM string { $$ = sdc_set_false_path_add_to_from_group($1, make_sdc_string_group(SDC_STRING, $3), SDC_FROM); free($3); }
| cmd_set_false_path ARG_TO string { $$ = sdc_set_false_path_add_to_from_group($1, make_sdc_string_group(SDC_STRING, $3), SDC_TO ); free($3); }
;
cmd_set_max_delay: CMD_SET_MAX_DELAY { $$ = alloc_sdc_set_max_delay(); }
| cmd_set_max_delay number { $$ = sdc_set_max_delay_set_max_delay_value($1, $2); }
| cmd_set_max_delay ARG_FROM '[' cmd_get_clocks ']' { $$ = sdc_set_max_delay_add_to_from_group($1, $4, SDC_FROM); free_sdc_string_group($4); }
| cmd_set_max_delay ARG_TO '[' cmd_get_clocks ']' { $$ = sdc_set_max_delay_add_to_from_group($1, $4, SDC_TO ); free_sdc_string_group($4); }
| cmd_set_max_delay ARG_FROM '{' stringGroup '}' { $$ = sdc_set_max_delay_add_to_from_group($1, $4, SDC_FROM); free_sdc_string_group($4); }
| cmd_set_max_delay ARG_TO '{' stringGroup '}' { $$ = sdc_set_max_delay_add_to_from_group($1, $4, SDC_TO ); free_sdc_string_group($4); }
| cmd_set_max_delay ARG_FROM string { $$ = sdc_set_max_delay_add_to_from_group($1, make_sdc_string_group(SDC_STRING, $3), SDC_FROM); free($3); }
| cmd_set_max_delay ARG_TO string { $$ = sdc_set_max_delay_add_to_from_group($1, make_sdc_string_group(SDC_STRING, $3), SDC_TO ); free($3); }
;
cmd_set_multicycle_path: CMD_SET_MULTICYCLE_PATH { $$ = alloc_sdc_set_multicycle_path(); }
| cmd_set_multicycle_path int_number { $$ = sdc_set_multicycle_path_set_mcp_value($1, $2); }
| cmd_set_multicycle_path ARG_SETUP { $$ = sdc_set_multicycle_path_set_type($1, SDC_MCP_SETUP); }
| cmd_set_multicycle_path ARG_FROM '[' cmd_get_clocks ']' { $$ = sdc_set_multicycle_path_add_to_from_group($1, $4, SDC_FROM); free_sdc_string_group($4); }
| cmd_set_multicycle_path ARG_TO '[' cmd_get_clocks ']' { $$ = sdc_set_multicycle_path_add_to_from_group($1, $4, SDC_TO ); free_sdc_string_group($4); }
| cmd_set_multicycle_path ARG_FROM '{' stringGroup '}' { $$ = sdc_set_multicycle_path_add_to_from_group($1, $4, SDC_FROM); free_sdc_string_group($4); }
| cmd_set_multicycle_path ARG_TO '{' stringGroup '}' { $$ = sdc_set_multicycle_path_add_to_from_group($1, $4, SDC_TO ); free_sdc_string_group($4); }
| cmd_set_multicycle_path ARG_FROM string { $$ = sdc_set_multicycle_path_add_to_from_group($1, make_sdc_string_group(SDC_STRING, $3), SDC_FROM); free($3); }
| cmd_set_multicycle_path ARG_TO string { $$ = sdc_set_multicycle_path_add_to_from_group($1, make_sdc_string_group(SDC_STRING, $3), SDC_TO ); free($3); }
;
cmd_get_ports: CMD_GET_PORTS { $$ = alloc_sdc_string_group(SDC_PORT); }
| cmd_get_ports '{' stringGroup '}' { $$ = sdc_string_group_add_strings($1, $3); free_sdc_string_group($3); }
| cmd_get_ports string { $$ = sdc_string_group_add_string($1, $2); free($2); }
;
cmd_get_clocks: CMD_GET_CLOCKS { $$ = alloc_sdc_string_group(SDC_CLOCK); }
| cmd_get_clocks '{' stringGroup '}' { $$ = sdc_string_group_add_strings($1, $3); free_sdc_string_group($3); }
| cmd_get_clocks string { $$ = sdc_string_group_add_string($1, $2); free($2); }
;
stringGroup: /*empty*/ { $$ = alloc_sdc_string_group(SDC_STRING); }
| stringGroup string { $$ = sdc_string_group_add_string($1, $2); free($2); }
string: STRING { $$ = $1; }
| ESCAPED_STRING { $$ = $1; }
;
number: float_number { $$ = $1; }
| int_number { $$ = $1; }
;
float_number: FLOAT_NUMBER { $$ = $1; }
;
int_number: INT_NUMBER { $$ = $1; }
;
%%
int yyerror(const char *msg) {
sdc_error(yylineno, yytext, "%s\n", msg);
return 1;
}