/* C++ parsers require Bison 3 */ %require "3.0" %language "C++" /* Write-out tokens header file */ %defines /* Use Bison's 'variant' to store values. * This allows us to use non POD types (e.g. * with constructors/destrictors), which is * not possible with the default mode which * uses unions. */ %define api.value.type variant /* * Use the 'complete' symbol type (i.e. variant) * in the lexer */ %define api.token.constructor /* * Add a prefix the make_* functions used to * create the symbols */ %define api.token.prefix {TOKEN_} /* * Use a re-entrant (no global vars) parser */ /*%define api.pure full*/ /* Wrap everything in our namespace */ %define api.namespace {tatumparse} /* Name the parser class */ %define parser_class_name {Parser} /* Match the flex prefix */ %define api.prefix {tatumparse_} /* Extra checks for correct usage */ %define parse.assert /* Enable debugging info */ %define parse.trace /* Better error reporting */ %define parse.error verbose /* * Fixes inaccuracy in verbose error reporting. * May be slow for some grammars. */ /*%define parse.lac full*/ /* Track locations */ /*%locations*/ /* Generate a table of token names */ %token-table %lex-param {Lexer& lexer} %parse-param {Lexer& lexer} %parse-param {Callback& callback} %code requires { #include #include "tatumparse.hpp" #include "tatumparse/tatumparse_lexer_fwd.hpp" } %code top { #include "tatumparse/tatumparse_lexer.hpp" //Bison calls tatumparse_lex() to get the next token. //We use the Lexer class as the interface to the lexer, so we //re-defined the function to tell Bison how to get the next token. static tatumparse::Parser::symbol_type tatumparse_lex(tatumparse::Lexer& lexer) { return lexer.next_token(); } } %{ #include #include #include "assert.h" #include "tatumparse.hpp" #include "tatumparse/tatumparse_common.hpp" #include "tatumparse/tatumparse_error.hpp" using namespace tatumparse; %} /* Declare constant */ %token TIMING_GRAPH "timing_graph:" %token NODE "node:" %token TYPE "type:" %token SOURCE "SOURCE" %token SINK "SINK" %token IPIN "IPIN" %token OPIN "OPIN" %token CPIN "CPIN" %token IN_EDGES "in_edges:" %token OUT_EDGES "out_edges:" %token EDGE "edge:" %token SRC_NODE "src_node:" %token SINK_NODE "sink_node:" %token DISABLED "disabled:" %token PRIMITIVE_COMBINATIONAL "PRIMITIVE_COMBINATIONAL" %token PRIMITIVE_CLOCK_LAUNCH "PRIMITIVE_CLOCK_LAUNCH" %token PRIMITIVE_CLOCK_CAPTURE "PRIMITIVE_CLOCK_CAPTURE" %token INTERCONNECT "INTERCONNECT" %token TRUE "true" %token FALSE "false" %token TIMING_CONSTRAINTS "timing_constraints:" %token CLOCK "CLOCK" %token CLOCK_SOURCE "CLOCK_SOURCE" %token CONSTANT_GENERATOR "CONSTANT_GENERATOR" %token MAX_INPUT_CONSTRAINT "MAX_INPUT_CONSTRAINT" %token MIN_INPUT_CONSTRAINT "MIN_INPUT_CONSTRAINT" %token MAX_OUTPUT_CONSTRAINT "MAX_OUTPUT_CONSTRAINT" %token MIN_OUTPUT_CONSTRAINT "MIN_OUTPUT_CONSTRAINT" %token SETUP_CONSTRAINT "SETUP_CONSTRAINT" %token HOLD_CONSTRAINT "HOLD_CONSTRAINT" %token SETUP_UNCERTAINTY "SETUP_UNCERTAINTY" %token HOLD_UNCERTAINTY "HOLD_UNCERTAINTY" %token EARLY_SOURCE_LATENCY "EARLY_SOURCE_LATENCY" %token LATE_SOURCE_LATENCY "LATE_SOURCE_LATENCY" %token DOMAIN "domain:" %token NAME "name:" %token CONSTRAINT "constraint:" %token UNCERTAINTY "uncertainty:" %token LATENCY "latency:" %token LAUNCH_DOMAIN "launch_domain:" %token CAPTURE_DOMAIN "capture_domain:" %token CAPTURE_NODE "capture_node:" %token DELAY_MODEL "delay_model:" %token MIN_DELAY "min_delay:" %token MAX_DELAY "max_delay:" %token SETUP_TIME "setup_time:" %token HOLD_TIME "hold_time:" %token ANALYSIS_RESULTS "analysis_results:" %token SETUP_DATA "SETUP_DATA" %token SETUP_DATA_ARRIVAL "SETUP_DATA_ARRIVAL" %token SETUP_DATA_REQUIRED "SETUP_DATA_REQUIRED" %token SETUP_LAUNCH_CLOCK "SETUP_LAUNCH_CLOCK" %token SETUP_CAPTURE_CLOCK "SETUP_CAPTURE_CLOCK" %token SETUP_SLACK "SETUP_SLACK" %token HOLD_DATA "HOLD_DATA" %token HOLD_DATA_ARRIVAL "HOLD_DATA_ARRIVAL" %token HOLD_DATA_REQUIRED "HOLD_DATA_REQUIRED" %token HOLD_LAUNCH_CLOCK "HOLD_LAUNCH_CLOCK" %token HOLD_CAPTURE_CLOCK "HOLD_CAPTURE_CLOCK" %token HOLD_SLACK "HOLD_SLACK" %token TIME "time:" %token SLACK "slack:" %token EOL "end-of-line" %token EOF 0 "end-of-file" /* declare variable tokens */ %token STRING %token INT %token FLOAT /* declare types */ %type NodeId %type SrcNodeId %type SinkNodeId %type EdgeId %type NodeType %type EdgeType %type > IntList %type > InEdges %type > OutEdges %type DomainId %type LaunchDomainId %type CaptureDomainId %type CaptureNodeId %type Constraint %type Uncertainty %type Latency %type Name %type Number %type MaxDelay %type MinDelay %type SetupTime %type HoldTime %type Time %type Slack %type TagType %type Disabled %type Bool /* Top level rule */ %start tatum_data %% tatum_data: /*empty*/ { } | tatum_data Graph { callback.finish_graph(); } | tatum_data Constraints { callback.finish_constraints(); } | tatum_data DelayModel { callback.finish_delay_model(); } | tatum_data Results { callback.finish_results(); } | tatum_data EOL { /*eat stray EOL */ } Graph: TIMING_GRAPH EOL { callback.start_graph(); } | Graph NodeId NodeType InEdges OutEdges EOL { callback.add_node($2, $3, $4, $4); } | Graph EdgeId EdgeType SrcNodeId SinkNodeId Disabled EOL { callback.add_edge($2, $3, $4, $5, $6); } Constraints: TIMING_CONSTRAINTS EOL { callback.start_constraints(); } | Constraints TYPE CLOCK DomainId Name EOL { callback.add_clock_domain($4, $5); } | Constraints TYPE CLOCK_SOURCE NodeId DomainId EOL { callback.add_clock_source($4, $5); } | Constraints TYPE CONSTANT_GENERATOR NodeId EOL { callback.add_constant_generator($4); } | Constraints TYPE MAX_INPUT_CONSTRAINT NodeId DomainId Constraint EOL { callback.add_max_input_constraint($4, $5, $6); } | Constraints TYPE MIN_INPUT_CONSTRAINT NodeId DomainId Constraint EOL { callback.add_min_input_constraint($4, $5, $6); } | Constraints TYPE MAX_OUTPUT_CONSTRAINT NodeId DomainId Constraint EOL { callback.add_max_output_constraint($4, $5, $6); } | Constraints TYPE MIN_OUTPUT_CONSTRAINT NodeId DomainId Constraint EOL { callback.add_min_output_constraint($4, $5, $6); } | Constraints TYPE SETUP_CONSTRAINT LaunchDomainId CaptureDomainId Constraint EOL { callback.add_setup_constraint($4, $5, -1, $6); } | Constraints TYPE HOLD_CONSTRAINT LaunchDomainId CaptureDomainId Constraint EOL { callback.add_hold_constraint($4, $5, -1, $6); } | Constraints TYPE SETUP_CONSTRAINT LaunchDomainId CaptureDomainId CaptureNodeId Constraint EOL { callback.add_setup_constraint($4, $5, $6, $7); } | Constraints TYPE HOLD_CONSTRAINT LaunchDomainId CaptureDomainId CaptureNodeId Constraint EOL { callback.add_hold_constraint($4, $5, $6, $7); } | Constraints TYPE SETUP_UNCERTAINTY LaunchDomainId CaptureDomainId Uncertainty EOL { callback.add_setup_uncertainty($4, $5, $6); } | Constraints TYPE HOLD_UNCERTAINTY LaunchDomainId CaptureDomainId Uncertainty EOL { callback.add_hold_uncertainty($4, $5, $6); } | Constraints TYPE EARLY_SOURCE_LATENCY DomainId Latency EOL { callback.add_early_source_latency($4, $5); } | Constraints TYPE LATE_SOURCE_LATENCY DomainId Latency EOL { callback.add_late_source_latency($4, $5); } DelayModel: DELAY_MODEL EOL { callback.start_delay_model(); } | DelayModel EdgeId MinDelay MaxDelay EOL { callback.add_edge_delay($2, $3, $4); } | DelayModel EdgeId SetupTime HoldTime EOL { callback.add_edge_setup_hold_time($2, $3, $4); } Results: ANALYSIS_RESULTS EOL { callback.start_results(); } | Results TagType NodeId LaunchDomainId CaptureDomainId Time EOL { callback.add_node_tag($2, $3, $4, $5, NAN); } | Results TagType EdgeId LaunchDomainId CaptureDomainId Slack EOL { callback.add_edge_slack($2, $3, $4, $5, NAN); } | Results TagType NodeId LaunchDomainId CaptureDomainId Slack EOL { callback.add_node_slack($2, $3, $4, $5, NAN); } Time: TIME Number { $$ = $2; } Slack: SLACK Number { $$ = $2; } TagType: TYPE SETUP_DATA_ARRIVAL { $$ = TagType::SETUP_DATA_ARRIVAL; } | TYPE SETUP_DATA_REQUIRED { $$ = TagType::SETUP_DATA_REQUIRED; } | TYPE SETUP_LAUNCH_CLOCK { $$ = TagType::SETUP_LAUNCH_CLOCK; } | TYPE SETUP_CAPTURE_CLOCK { $$ = TagType::SETUP_CAPTURE_CLOCK; } | TYPE SETUP_SLACK { $$ = TagType::SETUP_SLACK; } | TYPE HOLD_DATA_ARRIVAL { $$ = TagType::HOLD_DATA_ARRIVAL; } | TYPE HOLD_DATA_REQUIRED { $$ = TagType::HOLD_DATA_REQUIRED; } | TYPE HOLD_LAUNCH_CLOCK { $$ = TagType::HOLD_LAUNCH_CLOCK; } | TYPE HOLD_CAPTURE_CLOCK { $$ = TagType::HOLD_CAPTURE_CLOCK; } | TYPE HOLD_SLACK { $$ = TagType::HOLD_SLACK; } MaxDelay: MAX_DELAY Number { $$ = $2; } MinDelay: MIN_DELAY Number { $$ = $2; } SetupTime: SETUP_TIME Number { $$ = $2; } HoldTime: HOLD_TIME Number { $$ = $2; } DomainId: DOMAIN INT { $$ = $2; } LaunchDomainId: LAUNCH_DOMAIN INT { $$ = $2; } CaptureDomainId: CAPTURE_DOMAIN INT { $$ = $2; } CaptureNodeId: CAPTURE_NODE INT { $$ = $2; } Constraint: CONSTRAINT Number { $$ = $2; } Uncertainty: UNCERTAINTY Number { $$ = $2; } Latency: LATENCY Number { $$ = $2; } Name: NAME STRING { $$ = $2; } NodeType: TYPE SOURCE { $$ = NodeType::SOURCE; } | TYPE SINK { $$ = NodeType::SINK; } | TYPE IPIN { $$ = NodeType::IPIN; } | TYPE OPIN { $$ = NodeType::OPIN; } | TYPE CPIN { $$ = NodeType::CPIN; } EdgeType: TYPE PRIMITIVE_COMBINATIONAL { $$ = EdgeType::PRIMITIVE_COMBINATIONAL; } | TYPE PRIMITIVE_CLOCK_LAUNCH { $$ = EdgeType::PRIMITIVE_CLOCK_LAUNCH; } | TYPE PRIMITIVE_CLOCK_CAPTURE { $$ = EdgeType::PRIMITIVE_CLOCK_CAPTURE; } | TYPE INTERCONNECT { $$ = EdgeType::INTERCONNECT; } NodeId: NODE INT { $$ = $2;} InEdges: IN_EDGES IntList { $$ = $2; } OutEdges: OUT_EDGES IntList { $$ = $2; } EdgeId: EDGE INT { $$ = $2; } SrcNodeId: SRC_NODE INT { $$ = $2; } SinkNodeId: SINK_NODE INT { $$ = $2; } Disabled: /* Unsipecified*/ { $$ = false; } | DISABLED Bool { $$ = $2; } Bool: TRUE { $$ = true; } | FALSE { $$ = false; } IntList: /*empty*/ { $$ = std::vector(); } | IntList INT { $$ = std::move($1); $$.push_back($2); } Number: INT { $$ = $1; } | FLOAT { $$ = $1; } %% void tatumparse::Parser::error(const std::string& msg) { tatum_error_wrap(callback, lexer.lineno(), lexer.text(), msg.c_str()); }