Created
November 25, 2019 01:03
-
-
Save duck2/fd5b99c866d2e4779667635e5b844c10 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* This file is generated by uxsdcxx 0.1.0. | |
* https://github.com/duck2/uxsdcxx | |
* Modify only if your build process doesn't involve regenerating this file. | |
* | |
* Cmdline: uxsdcxx.py rr_graph.xsd | |
* Input file: /home/duck2/uxsdcxx/rr_graph.xsd | |
* md5sum of input file: 86ad1829ffcbd56309275e329a54a96f | |
*/ | |
#include <bitset> | |
#include <cassert> | |
#include <cstring> | |
#include <iostream> | |
#include <memory> | |
#include <string> | |
#include <vector> | |
#include <error.h> | |
#include <stddef.h> | |
#include <stdint.h> | |
#include "pugixml.hpp" | |
/* All uxsdcxx functions and structs live in this namespace. */ | |
namespace uxsd { | |
/* Enum tokens generated from XSD enumerations. */ | |
enum class enum_switch_type {UXSD_INVALID = 0, MUX, TRISTATE, PASS_GATE, SHORT, BUFFER}; | |
enum class enum_pin_type {UXSD_INVALID = 0, OPEN, OUTPUT, INPUT}; | |
enum class enum_loc_side {UXSD_INVALID = 0, LEFT, RIGHT, TOP, BOTTOM}; | |
enum class enum_node_type {UXSD_INVALID = 0, CHANX, CHANY, SOURCE, SINK, OPIN, IPIN}; | |
enum class enum_node_direction {UXSD_INVALID = 0, INC_DIR, DEC_DIR, BI_DIR}; | |
/* Base class for the schema. */ | |
class RrGraphBase { | |
public: | |
/** Generated for complex type "channel": | |
* <xs:complexType name="channel"> | |
* <xs:attribute name="chan_width_max" type="xs:int" use="required" /> | |
* <xs:attribute name="x_min" type="xs:int" use="required" /> | |
* <xs:attribute name="y_min" type="xs:int" use="required" /> | |
* <xs:attribute name="x_max" type="xs:int" use="required" /> | |
* <xs:attribute name="y_max" type="xs:int" use="required" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_channel_chan_width_max(int chan_width_max, void * data) = 0; | |
virtual inline void set_channel_x_max(int x_max, void * data) = 0; | |
virtual inline void set_channel_x_min(int x_min, void * data) = 0; | |
virtual inline void set_channel_y_max(int y_max, void * data) = 0; | |
virtual inline void set_channel_y_min(int y_min, void * data) = 0; | |
/** Generated for complex type "x_list": | |
* <xs:complexType name="x_list"> | |
* <xs:attribute name="index" type="xs:unsignedInt" use="required" /> | |
* <xs:attribute name="info" type="xs:int" use="required" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_x_list_index(unsigned int index, void * data) = 0; | |
virtual inline void set_x_list_info(int info, void * data) = 0; | |
/** Generated for complex type "y_list": | |
* <xs:complexType name="y_list"> | |
* <xs:attribute name="index" type="xs:unsignedInt" use="required" /> | |
* <xs:attribute name="info" type="xs:int" use="required" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_y_list_index(unsigned int index, void * data) = 0; | |
virtual inline void set_y_list_info(int info, void * data) = 0; | |
/** Generated for complex type "timing": | |
* <xs:complexType name="timing"> | |
* <xs:attribute name="R" type="xs:float" use="required" /> | |
* <xs:attribute name="Cin" type="xs:float" use="required" /> | |
* <xs:attribute name="Cinternal" type="xs:float" use="required" /> | |
* <xs:attribute name="Cout" type="xs:float" use="required" /> | |
* <xs:attribute name="Tdel" type="xs:float" use="required" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_timing_Cin(float Cin, void * data) = 0; | |
virtual inline void set_timing_Cinternal(float Cinternal, void * data) = 0; | |
virtual inline void set_timing_Cout(float Cout, void * data) = 0; | |
virtual inline void set_timing_R(float R, void * data) = 0; | |
virtual inline void set_timing_Tdel(float Tdel, void * data) = 0; | |
/** Generated for complex type "sizing": | |
* <xs:complexType name="sizing"> | |
* <xs:attribute name="mux_trans_size" type="xs:float" use="required" /> | |
* <xs:attribute name="buf_size" type="xs:float" use="required" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_sizing_buf_size(float buf_size, void * data) = 0; | |
virtual inline void set_sizing_mux_trans_size(float mux_trans_size, void * data) = 0; | |
/** Generated for complex type "switch": | |
* <xs:complexType name="switch"> | |
* <xs:all> | |
* <xs:element minOccurs="0" name="timing" type="timing" /> | |
* <xs:element name="sizing" type="sizing" /> | |
* </xs:all> | |
* <xs:attribute name="id" type="xs:int" use="required" /> | |
* <xs:attribute name="name" type="xs:string" use="required" /> | |
* <xs:attribute name="type" type="switch_type" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_switch_id(int id, void * data) = 0; | |
virtual inline void set_switch_name(const char * name, void * data) = 0; | |
virtual inline void set_switch_type(enum_switch_type type, void * data) = 0; | |
virtual inline void * init_switch_timing(void * data) = 0; | |
virtual inline void * init_switch_sizing(void * data) = 0; | |
/** Generated for complex type "segment_timing": | |
* <xs:complexType name="segment_timing"> | |
* <xs:attribute name="R_per_meter" type="xs:float" /> | |
* <xs:attribute name="C_per_meter" type="xs:float" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_segment_timing_C_per_meter(float C_per_meter, void * data) = 0; | |
virtual inline void set_segment_timing_R_per_meter(float R_per_meter, void * data) = 0; | |
/** Generated for complex type "segment": | |
* <xs:complexType name="segment"> | |
* <xs:all> | |
* <xs:element minOccurs="0" name="timing" type="segment_timing" /> | |
* </xs:all> | |
* <xs:attribute name="id" type="xs:int" use="required" /> | |
* <xs:attribute name="name" type="xs:string" use="required" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_segment_id(int id, void * data) = 0; | |
virtual inline void set_segment_name(const char * name, void * data) = 0; | |
virtual inline void * init_segment_timing(void * data) = 0; | |
/** Generated for complex type "pin": | |
* <xs:complexType name="pin"> | |
* <xs:simpleContent> | |
* <xs:extension base="xs:string"> | |
* <xs:attribute name="ptc" type="xs:int" use="required" /> | |
* </xs:extension> | |
* </xs:simpleContent> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_pin_ptc(int ptc, void * data) = 0; | |
virtual inline void set_pin_value(const char * value, void * data) = 0; | |
/** Generated for complex type "pin_class": | |
* <xs:complexType name="pin_class"> | |
* <xs:sequence> | |
* <xs:element maxOccurs="unbounded" name="pin" type="pin" /> | |
* </xs:sequence> | |
* <xs:attribute name="type" type="pin_type" use="required" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_pin_class_type(enum_pin_type type, void * data) = 0; | |
virtual inline void * add_pin_class_pin(void * data) = 0; | |
/** Generated for complex type "meta": | |
* <xs:complexType name="meta"> | |
* <xs:simpleContent> | |
* <xs:extension base="xs:string"> | |
* <xs:attribute name="name" type="xs:string" use="required" /> | |
* </xs:extension> | |
* </xs:simpleContent> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_meta_name(const char * name, void * data) = 0; | |
virtual inline void set_meta_value(const char * value, void * data) = 0; | |
/** Generated for complex type "metadata": | |
* <xs:complexType name="metadata"> | |
* <xs:sequence> | |
* <xs:element maxOccurs="unbounded" name="meta" type="meta" /> | |
* </xs:sequence> | |
* </xs:complexType> | |
*/ | |
virtual inline void * add_metadata_meta(void * data) = 0; | |
/** Generated for complex type "block_type": | |
* <xs:complexType name="block_type"> | |
* <xs:sequence> | |
* <xs:element maxOccurs="unbounded" minOccurs="0" name="pin_class" type="pin_class" /> | |
* </xs:sequence> | |
* <xs:attribute name="id" type="xs:int" use="required" /> | |
* <xs:attribute name="name" type="xs:string" use="required" /> | |
* <xs:attribute name="width" type="xs:int" use="required" /> | |
* <xs:attribute name="height" type="xs:int" use="required" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_block_type_height(int height, void * data) = 0; | |
virtual inline void set_block_type_id(int id, void * data) = 0; | |
virtual inline void set_block_type_name(const char * name, void * data) = 0; | |
virtual inline void set_block_type_width(int width, void * data) = 0; | |
virtual inline void * add_block_type_pin_class(void * data) = 0; | |
/** Generated for complex type "grid_loc": | |
* <xs:complexType name="grid_loc"> | |
* <xs:attribute name="x" type="xs:int" use="required" /> | |
* <xs:attribute name="y" type="xs:int" use="required" /> | |
* <xs:attribute name="block_type_id" type="xs:int" use="required" /> | |
* <xs:attribute name="width_offset" type="xs:int" use="required" /> | |
* <xs:attribute name="height_offset" type="xs:int" use="required" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_grid_loc_block_type_id(int block_type_id, void * data) = 0; | |
virtual inline void set_grid_loc_height_offset(int height_offset, void * data) = 0; | |
virtual inline void set_grid_loc_width_offset(int width_offset, void * data) = 0; | |
virtual inline void set_grid_loc_x(int x, void * data) = 0; | |
virtual inline void set_grid_loc_y(int y, void * data) = 0; | |
/** Generated for complex type "node_loc": | |
* <xs:complexType name="node_loc"> | |
* <xs:attribute name="xlow" type="xs:int" use="required" /> | |
* <xs:attribute name="ylow" type="xs:int" use="required" /> | |
* <xs:attribute name="xhigh" type="xs:int" use="required" /> | |
* <xs:attribute name="yhigh" type="xs:int" use="required" /> | |
* <xs:attribute name="side" type="loc_side" /> | |
* <xs:attribute name="ptc" type="xs:int" use="required" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_node_loc_ptc(int ptc, void * data) = 0; | |
virtual inline void set_node_loc_side(enum_loc_side side, void * data) = 0; | |
virtual inline void set_node_loc_xhigh(int xhigh, void * data) = 0; | |
virtual inline void set_node_loc_xlow(int xlow, void * data) = 0; | |
virtual inline void set_node_loc_yhigh(int yhigh, void * data) = 0; | |
virtual inline void set_node_loc_ylow(int ylow, void * data) = 0; | |
/** Generated for complex type "node_timing": | |
* <xs:complexType name="node_timing"> | |
* <xs:attribute name="R" type="xs:float" use="required" /> | |
* <xs:attribute name="C" type="xs:float" use="required" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_node_timing_C(float C, void * data) = 0; | |
virtual inline void set_node_timing_R(float R, void * data) = 0; | |
/** Generated for complex type "node_segment": | |
* <xs:complexType name="node_segment"> | |
* <xs:attribute name="segment_id" type="xs:int" use="required" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_node_segment_segment_id(int segment_id, void * data) = 0; | |
/** Generated for complex type "node_connection_box": | |
* <xs:complexType name="node_connection_box"> | |
* <xs:attribute name="id" type="xs:int" use="required" /> | |
* <xs:attribute name="x" type="xs:int" use="required" /> | |
* <xs:attribute name="y" type="xs:int" use="required" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_node_connection_box_id(int id, void * data) = 0; | |
virtual inline void set_node_connection_box_x(int x, void * data) = 0; | |
virtual inline void set_node_connection_box_y(int y, void * data) = 0; | |
/** Generated for complex type "node_canonical_loc": | |
* <xs:complexType name="node_canonical_loc"> | |
* <xs:attribute name="x" type="xs:int" use="required" /> | |
* <xs:attribute name="y" type="xs:int" use="required" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_node_canonical_loc_x(int x, void * data) = 0; | |
virtual inline void set_node_canonical_loc_y(int y, void * data) = 0; | |
/** Generated for complex type "node": | |
* <xs:complexType name="node"> | |
* <xs:all> | |
* <xs:element name="loc" type="node_loc" /> | |
* <xs:element minOccurs="0" name="timing" type="node_timing" /> | |
* <xs:element minOccurs="0" name="segment" type="node_segment" /> | |
* <xs:element minOccurs="0" name="connection_box" type="node_connection_box" /> | |
* <xs:element minOccurs="0" name="canonical_loc" type="node_canonical_loc" /> | |
* <xs:element minOccurs="0" name="metadata" type="metadata" /> | |
* </xs:all> | |
* <xs:attribute name="id" type="xs:unsignedInt" use="required" /> | |
* <xs:attribute name="type" type="node_type" use="required" /> | |
* <xs:attribute name="direction" type="node_direction" /> | |
* <xs:attribute name="capacity" type="xs:unsignedInt" use="required" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_node_capacity(unsigned int capacity, void * data) = 0; | |
virtual inline void set_node_direction(enum_node_direction direction, void * data) = 0; | |
virtual inline void set_node_id(unsigned int id, void * data) = 0; | |
virtual inline void set_node_type(enum_node_type type, void * data) = 0; | |
virtual inline void * init_node_loc(void * data) = 0; | |
virtual inline void * init_node_timing(void * data) = 0; | |
virtual inline void * init_node_segment(void * data) = 0; | |
virtual inline void * init_node_connection_box(void * data) = 0; | |
virtual inline void * init_node_canonical_loc(void * data) = 0; | |
virtual inline void * init_node_metadata(void * data) = 0; | |
/** Generated for complex type "edge": | |
* <xs:complexType name="edge"> | |
* <xs:all> | |
* <xs:element minOccurs="0" name="metadata" type="metadata" /> | |
* </xs:all> | |
* <xs:attribute name="id" type="xs:unsignedInt" /> | |
* <xs:attribute name="src_node" type="xs:unsignedInt" use="required" /> | |
* <xs:attribute name="sink_node" type="xs:unsignedInt" use="required" /> | |
* <xs:attribute name="switch_id" type="xs:unsignedInt" use="required" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_edge_id(unsigned int id, void * data) = 0; | |
virtual inline void set_edge_sink_node(unsigned int sink_node, void * data) = 0; | |
virtual inline void set_edge_src_node(unsigned int src_node, void * data) = 0; | |
virtual inline void set_edge_switch_id(unsigned int switch_id, void * data) = 0; | |
virtual inline void * init_edge_metadata(void * data) = 0; | |
/** Generated for complex type "channels": | |
* <xs:complexType name="channels"> | |
* <xs:sequence> | |
* <xs:element name="channel" type="channel" /> | |
* <xs:element maxOccurs="unbounded" name="x_list" type="x_list" /> | |
* <xs:element maxOccurs="unbounded" name="y_list" type="y_list" /> | |
* </xs:sequence> | |
* </xs:complexType> | |
*/ | |
virtual inline void * init_channels_channel(void * data) = 0; | |
virtual inline void * add_channels_x_list(void * data) = 0; | |
virtual inline void * add_channels_y_list(void * data) = 0; | |
/** Generated for complex type "switches": | |
* <xs:complexType name="switches"> | |
* <xs:sequence> | |
* <xs:element maxOccurs="unbounded" name="switch" type="switch" /> | |
* </xs:sequence> | |
* </xs:complexType> | |
*/ | |
virtual inline void * add_switches_switch(void * data) = 0; | |
/** Generated for complex type "segments": | |
* <xs:complexType name="segments"> | |
* <xs:sequence> | |
* <xs:element maxOccurs="unbounded" name="segment" type="segment" /> | |
* </xs:sequence> | |
* </xs:complexType> | |
*/ | |
virtual inline void * add_segments_segment(void * data) = 0; | |
/** Generated for complex type "block_types": | |
* <xs:complexType name="block_types"> | |
* <xs:sequence> | |
* <xs:element maxOccurs="unbounded" name="block_type" type="block_type" /> | |
* </xs:sequence> | |
* </xs:complexType> | |
*/ | |
virtual inline void * add_block_types_block_type(void * data) = 0; | |
/** Generated for complex type "grid_locs": | |
* <xs:complexType name="grid_locs"> | |
* <xs:sequence> | |
* <xs:element maxOccurs="unbounded" name="grid_loc" type="grid_loc" /> | |
* </xs:sequence> | |
* </xs:complexType> | |
*/ | |
virtual inline void * add_grid_locs_grid_loc(void * data) = 0; | |
/** Generated for complex type "rr_nodes": | |
* <xs:complexType name="rr_nodes"> | |
* <xs:choice maxOccurs="unbounded"> | |
* <xs:element name="node" type="node" /> | |
* </xs:choice> | |
* </xs:complexType> | |
*/ | |
virtual inline void * add_rr_nodes_node(void * data) = 0; | |
/** Generated for complex type "rr_edges": | |
* <xs:complexType name="rr_edges"> | |
* <xs:choice maxOccurs="unbounded"> | |
* <xs:element name="edge" type="edge" /> | |
* </xs:choice> | |
* </xs:complexType> | |
*/ | |
virtual inline void * add_rr_edges_edge(void * data) = 0; | |
/** Generated for complex type "bin_nodes": | |
* <xs:complexType name="bin_nodes"> | |
* <xs:attribute name="file" type="xs:string" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_bin_nodes_file(const char * file, void * data) = 0; | |
/** Generated for complex type "connection_box": | |
* <xs:complexType name="connection_box"> | |
* <xs:attribute name="id" type="xs:unsignedInt" use="required" /> | |
* <xs:attribute name="name" type="xs:string" use="required" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_connection_box_id(unsigned int id, void * data) = 0; | |
virtual inline void set_connection_box_name(const char * name, void * data) = 0; | |
/** Generated for complex type "connection_boxes": | |
* <xs:complexType name="connection_boxes"> | |
* <xs:sequence> | |
* <xs:element maxOccurs="unbounded" name="connection_box" type="connection_box" /> | |
* </xs:sequence> | |
* <xs:attribute name="x_dim" type="xs:int" use="required" /> | |
* <xs:attribute name="y_dim" type="xs:int" use="required" /> | |
* <xs:attribute name="num_boxes" type="xs:unsignedInt" use="required" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_connection_boxes_num_boxes(unsigned int num_boxes, void * data) = 0; | |
virtual inline void set_connection_boxes_x_dim(int x_dim, void * data) = 0; | |
virtual inline void set_connection_boxes_y_dim(int y_dim, void * data) = 0; | |
virtual inline void * add_connection_boxes_connection_box(void * data) = 0; | |
/** Generated for complex type "rr_graph": | |
* <xs:complexType xmlns:xs="http://www.w3.org/2001/XMLSchema"> | |
* <xs:all> | |
* <xs:element minOccurs="0" name="binary_nodes_and_edges" type="bin_nodes" /> | |
* <xs:element minOccurs="0" name="connection_boxes" type="connection_boxes" /> | |
* <xs:element name="channels" type="channels" /> | |
* <xs:element name="switches" type="switches" /> | |
* <xs:element name="segments" type="segments" /> | |
* <xs:element name="block_types" type="block_types" /> | |
* <xs:element name="grid" type="grid_locs" /> | |
* <xs:element name="rr_nodes" type="rr_nodes" /> | |
* <xs:element name="rr_edges" type="rr_edges" /> | |
* </xs:all> | |
* <xs:attribute name="tool_name" type="xs:string" /> | |
* <xs:attribute name="tool_version" type="xs:string" /> | |
* <xs:attribute name="tool_comment" type="xs:string" /> | |
* </xs:complexType> | |
*/ | |
virtual inline void set_rr_graph_tool_comment(const char * tool_comment, void * data) = 0; | |
virtual inline void set_rr_graph_tool_name(const char * tool_name, void * data) = 0; | |
virtual inline void set_rr_graph_tool_version(const char * tool_version, void * data) = 0; | |
virtual inline void * init_rr_graph_binary_nodes_and_edges(void * data) = 0; | |
virtual inline void * init_rr_graph_connection_boxes(void * data) = 0; | |
virtual inline void * init_rr_graph_channels(void * data) = 0; | |
virtual inline void * init_rr_graph_switches(void * data) = 0; | |
virtual inline void * init_rr_graph_segments(void * data) = 0; | |
virtual inline void * init_rr_graph_block_types(void * data) = 0; | |
virtual inline void * init_rr_graph_grid(void * data) = 0; | |
virtual inline void * init_rr_graph_rr_nodes(void * data) = 0; | |
virtual inline void * init_rr_graph_rr_edges(void * data) = 0;}; | |
/* Declarations for internal load functions for the complex types. */ | |
template <class T> | |
void load_channel(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_x_list(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_y_list(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_timing(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_sizing(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_switch(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_segment_timing(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_segment(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_pin(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_pin_class(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_meta(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_metadata(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_block_type(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_grid_loc(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_node_loc(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_node_timing(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_node_segment(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_node_connection_box(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_node_canonical_loc(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_node(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_edge(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_channels(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_switches(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_segments(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_block_types(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_grid_locs(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_rr_nodes(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_rr_edges(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_bin_nodes(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_connection_box(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_connection_boxes(const pugi::xml_node &root, T &out, void *data); | |
template <class T> | |
void load_rr_graph(const pugi::xml_node &root, T &out, void *data); | |
/* Load function for the root element. */ | |
template <class T> | |
pugi::xml_parse_result load_rr_graph_xml(T &out, std::istream &is){ | |
static_assert(std::is_base_of<RrGraphBase, T>::value); | |
pugi::xml_document doc; | |
pugi::xml_parse_result result = doc.load(is); | |
if(!result) return result; | |
for(pugi::xml_node node= doc.first_child(); node; node = node.next_sibling()){ | |
if(std::strcmp(node.name(), "rr_graph") == 0){ | |
/* If errno is set up to this point, it messes with strtol errno checking. */ | |
errno = 0; | |
load_rr_graph(node, out, NULL); | |
} | |
else throw std::runtime_error("Invalid root-level element " + std::string(node.name())); | |
} | |
return result; | |
} | |
typedef const uint32_t __attribute__((aligned(1))) triehash_uu32; | |
typedef const uint64_t __attribute__((aligned(1))) triehash_uu64; | |
static_assert(alignof(triehash_uu32) == 1, "Unaligned 32-bit access not found."); | |
static_assert(alignof(triehash_uu64) == 1, "Unaligned 64-bit access not found."); | |
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ | |
#define onechar(c, s, l) (((uint64_t)(c)) << (s)) | |
#else | |
#define onechar(c, s, l) (((uint64_t)(c)) << (l-8-s)) | |
#endif | |
/* Tokens for attribute and node names. */ | |
enum class atok_t_channel {CHAN_WIDTH_MAX, X_MAX, X_MIN, Y_MAX, Y_MIN}; | |
static const char *atok_lookup_t_channel[] = {"chan_width_max", "x_max", "x_min", "y_max", "y_min"}; | |
enum class atok_t_x_list {INDEX, INFO}; | |
static const char *atok_lookup_t_x_list[] = {"index", "info"}; | |
enum class atok_t_y_list {INDEX, INFO}; | |
static const char *atok_lookup_t_y_list[] = {"index", "info"}; | |
enum class atok_t_timing {CIN, CINTERNAL, COUT, R, TDEL}; | |
static const char *atok_lookup_t_timing[] = {"Cin", "Cinternal", "Cout", "R", "Tdel"}; | |
enum class atok_t_sizing {BUF_SIZE, MUX_TRANS_SIZE}; | |
static const char *atok_lookup_t_sizing[] = {"buf_size", "mux_trans_size"}; | |
enum class gtok_t_switch {TIMING, SIZING}; | |
static const char *gtok_lookup_t_switch[] = {"timing", "sizing"};enum class atok_t_switch {ID, NAME, TYPE}; | |
static const char *atok_lookup_t_switch[] = {"id", "name", "type"}; | |
enum class atok_t_segment_timing {C_PER_METER, R_PER_METER}; | |
static const char *atok_lookup_t_segment_timing[] = {"C_per_meter", "R_per_meter"}; | |
enum class gtok_t_segment {TIMING}; | |
static const char *gtok_lookup_t_segment[] = {"timing"};enum class atok_t_segment {ID, NAME}; | |
static const char *atok_lookup_t_segment[] = {"id", "name"}; | |
enum class atok_t_pin {PTC}; | |
static const char *atok_lookup_t_pin[] = {"ptc"}; | |
enum class gtok_t_pin_class {PIN}; | |
static const char *gtok_lookup_t_pin_class[] = {"pin"};enum class atok_t_pin_class {TYPE}; | |
static const char *atok_lookup_t_pin_class[] = {"type"}; | |
enum class atok_t_meta {NAME}; | |
static const char *atok_lookup_t_meta[] = {"name"}; | |
enum class gtok_t_metadata {META}; | |
static const char *gtok_lookup_t_metadata[] = {"meta"}; | |
enum class gtok_t_block_type {PIN_CLASS}; | |
static const char *gtok_lookup_t_block_type[] = {"pin_class"};enum class atok_t_block_type {HEIGHT, ID, NAME, WIDTH}; | |
static const char *atok_lookup_t_block_type[] = {"height", "id", "name", "width"}; | |
enum class atok_t_grid_loc {BLOCK_TYPE_ID, HEIGHT_OFFSET, WIDTH_OFFSET, X, Y}; | |
static const char *atok_lookup_t_grid_loc[] = {"block_type_id", "height_offset", "width_offset", "x", "y"}; | |
enum class atok_t_node_loc {PTC, SIDE, XHIGH, XLOW, YHIGH, YLOW}; | |
static const char *atok_lookup_t_node_loc[] = {"ptc", "side", "xhigh", "xlow", "yhigh", "ylow"}; | |
enum class atok_t_node_timing {C, R}; | |
static const char *atok_lookup_t_node_timing[] = {"C", "R"}; | |
enum class atok_t_node_segment {SEGMENT_ID}; | |
static const char *atok_lookup_t_node_segment[] = {"segment_id"}; | |
enum class atok_t_node_connection_box {ID, X, Y}; | |
static const char *atok_lookup_t_node_connection_box[] = {"id", "x", "y"}; | |
enum class atok_t_node_canonical_loc {X, Y}; | |
static const char *atok_lookup_t_node_canonical_loc[] = {"x", "y"}; | |
enum class gtok_t_node {LOC, TIMING, SEGMENT, CONNECTION_BOX, CANONICAL_LOC, METADATA}; | |
static const char *gtok_lookup_t_node[] = {"loc", "timing", "segment", "connection_box", "canonical_loc", "metadata"};enum class atok_t_node {CAPACITY, DIRECTION, ID, TYPE}; | |
static const char *atok_lookup_t_node[] = {"capacity", "direction", "id", "type"}; | |
enum class gtok_t_edge {METADATA}; | |
static const char *gtok_lookup_t_edge[] = {"metadata"};enum class atok_t_edge {ID, SINK_NODE, SRC_NODE, SWITCH_ID}; | |
static const char *atok_lookup_t_edge[] = {"id", "sink_node", "src_node", "switch_id"}; | |
enum class gtok_t_channels {CHANNEL, X_LIST, Y_LIST}; | |
static const char *gtok_lookup_t_channels[] = {"channel", "x_list", "y_list"}; | |
enum class gtok_t_switches {SWITCH}; | |
static const char *gtok_lookup_t_switches[] = {"switch"}; | |
enum class gtok_t_segments {SEGMENT}; | |
static const char *gtok_lookup_t_segments[] = {"segment"}; | |
enum class gtok_t_block_types {BLOCK_TYPE}; | |
static const char *gtok_lookup_t_block_types[] = {"block_type"}; | |
enum class gtok_t_grid_locs {GRID_LOC}; | |
static const char *gtok_lookup_t_grid_locs[] = {"grid_loc"}; | |
enum class gtok_t_rr_nodes {NODE}; | |
static const char *gtok_lookup_t_rr_nodes[] = {"node"}; | |
enum class gtok_t_rr_edges {EDGE}; | |
static const char *gtok_lookup_t_rr_edges[] = {"edge"}; | |
enum class atok_t_bin_nodes {FILE}; | |
static const char *atok_lookup_t_bin_nodes[] = {"file"}; | |
enum class atok_t_connection_box {ID, NAME}; | |
static const char *atok_lookup_t_connection_box[] = {"id", "name"}; | |
enum class gtok_t_connection_boxes {CONNECTION_BOX}; | |
static const char *gtok_lookup_t_connection_boxes[] = {"connection_box"};enum class atok_t_connection_boxes {NUM_BOXES, X_DIM, Y_DIM}; | |
static const char *atok_lookup_t_connection_boxes[] = {"num_boxes", "x_dim", "y_dim"}; | |
enum class gtok_t_rr_graph {BINARY_NODES_AND_EDGES, CONNECTION_BOXES, CHANNELS, SWITCHES, SEGMENTS, BLOCK_TYPES, GRID, RR_NODES, RR_EDGES}; | |
static const char *gtok_lookup_t_rr_graph[] = {"binary_nodes_and_edges", "connection_boxes", "channels", "switches", "segments", "block_types", "grid", "rr_nodes", "rr_edges"};enum class atok_t_rr_graph {TOOL_COMMENT, TOOL_NAME, TOOL_VERSION}; | |
static const char *atok_lookup_t_rr_graph[] = {"tool_comment", "tool_name", "tool_version"}; | |
/* Internal lexers. These convert the PugiXML node names to input tokens. */ | |
inline atok_t_channel lex_attr_t_channel(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 5: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('x', 0, 32) | onechar('_', 8, 32) | onechar('m', 16, 32) | onechar('a', 24, 32): | |
switch(in[4]){ | |
case onechar('x', 0, 8): | |
return atok_t_channel::X_MAX; | |
break; | |
default: break; | |
} | |
break; | |
case onechar('x', 0, 32) | onechar('_', 8, 32) | onechar('m', 16, 32) | onechar('i', 24, 32): | |
switch(in[4]){ | |
case onechar('n', 0, 8): | |
return atok_t_channel::X_MIN; | |
break; | |
default: break; | |
} | |
break; | |
case onechar('y', 0, 32) | onechar('_', 8, 32) | onechar('m', 16, 32) | onechar('a', 24, 32): | |
switch(in[4]){ | |
case onechar('x', 0, 8): | |
return atok_t_channel::Y_MAX; | |
break; | |
default: break; | |
} | |
break; | |
case onechar('y', 0, 32) | onechar('_', 8, 32) | onechar('m', 16, 32) | onechar('i', 24, 32): | |
switch(in[4]){ | |
case onechar('n', 0, 8): | |
return atok_t_channel::Y_MIN; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 14: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('c', 0, 64) | onechar('h', 8, 64) | onechar('a', 16, 64) | onechar('n', 24, 64) | onechar('_', 32, 64) | onechar('w', 40, 64) | onechar('i', 48, 64) | onechar('d', 56, 64): | |
switch(*((triehash_uu32*)&in[8])){ | |
case onechar('t', 0, 32) | onechar('h', 8, 32) | onechar('_', 16, 32) | onechar('m', 24, 32): | |
switch(in[12]){ | |
case onechar('a', 0, 8): | |
switch(in[13]){ | |
case onechar('x', 0, 8): | |
return atok_t_channel::CHAN_WIDTH_MAX; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <channel>."); | |
} | |
inline atok_t_x_list lex_attr_t_x_list(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('i', 0, 32) | onechar('n', 8, 32) | onechar('f', 16, 32) | onechar('o', 24, 32): | |
return atok_t_x_list::INFO; | |
break; | |
default: break; | |
} | |
break; | |
case 5: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('i', 0, 32) | onechar('n', 8, 32) | onechar('d', 16, 32) | onechar('e', 24, 32): | |
switch(in[4]){ | |
case onechar('x', 0, 8): | |
return atok_t_x_list::INDEX; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <x_list>."); | |
} | |
inline atok_t_y_list lex_attr_t_y_list(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('i', 0, 32) | onechar('n', 8, 32) | onechar('f', 16, 32) | onechar('o', 24, 32): | |
return atok_t_y_list::INFO; | |
break; | |
default: break; | |
} | |
break; | |
case 5: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('i', 0, 32) | onechar('n', 8, 32) | onechar('d', 16, 32) | onechar('e', 24, 32): | |
switch(in[4]){ | |
case onechar('x', 0, 8): | |
return atok_t_y_list::INDEX; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <y_list>."); | |
} | |
inline atok_t_timing lex_attr_t_timing(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 1: | |
switch(in[0]){ | |
case onechar('R', 0, 8): | |
return atok_t_timing::R; | |
break; | |
default: break; | |
} | |
break; | |
case 3: | |
switch(in[0]){ | |
case onechar('C', 0, 8): | |
switch(in[1]){ | |
case onechar('i', 0, 8): | |
switch(in[2]){ | |
case onechar('n', 0, 8): | |
return atok_t_timing::CIN; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('C', 0, 32) | onechar('o', 8, 32) | onechar('u', 16, 32) | onechar('t', 24, 32): | |
return atok_t_timing::COUT; | |
break; | |
case onechar('T', 0, 32) | onechar('d', 8, 32) | onechar('e', 16, 32) | onechar('l', 24, 32): | |
return atok_t_timing::TDEL; | |
break; | |
default: break; | |
} | |
break; | |
case 9: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('C', 0, 64) | onechar('i', 8, 64) | onechar('n', 16, 64) | onechar('t', 24, 64) | onechar('e', 32, 64) | onechar('r', 40, 64) | onechar('n', 48, 64) | onechar('a', 56, 64): | |
switch(in[8]){ | |
case onechar('l', 0, 8): | |
return atok_t_timing::CINTERNAL; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <timing>."); | |
} | |
inline atok_t_sizing lex_attr_t_sizing(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 8: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('b', 0, 64) | onechar('u', 8, 64) | onechar('f', 16, 64) | onechar('_', 24, 64) | onechar('s', 32, 64) | onechar('i', 40, 64) | onechar('z', 48, 64) | onechar('e', 56, 64): | |
return atok_t_sizing::BUF_SIZE; | |
break; | |
default: break; | |
} | |
break; | |
case 14: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('m', 0, 64) | onechar('u', 8, 64) | onechar('x', 16, 64) | onechar('_', 24, 64) | onechar('t', 32, 64) | onechar('r', 40, 64) | onechar('a', 48, 64) | onechar('n', 56, 64): | |
switch(*((triehash_uu32*)&in[8])){ | |
case onechar('s', 0, 32) | onechar('_', 8, 32) | onechar('s', 16, 32) | onechar('i', 24, 32): | |
switch(in[12]){ | |
case onechar('z', 0, 8): | |
switch(in[13]){ | |
case onechar('e', 0, 8): | |
return atok_t_sizing::MUX_TRANS_SIZE; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <sizing>."); | |
} | |
inline gtok_t_switch lex_node_t_switch(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 6: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('s', 0, 32) | onechar('i', 8, 32) | onechar('z', 16, 32) | onechar('i', 24, 32): | |
switch(in[4]){ | |
case onechar('n', 0, 8): | |
switch(in[5]){ | |
case onechar('g', 0, 8): | |
return gtok_t_switch::SIZING; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case onechar('t', 0, 32) | onechar('i', 8, 32) | onechar('m', 16, 32) | onechar('i', 24, 32): | |
switch(in[4]){ | |
case onechar('n', 0, 8): | |
switch(in[5]){ | |
case onechar('g', 0, 8): | |
return gtok_t_switch::TIMING; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <switch>."); | |
} | |
inline atok_t_switch lex_attr_t_switch(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 2: | |
switch(in[0]){ | |
case onechar('i', 0, 8): | |
switch(in[1]){ | |
case onechar('d', 0, 8): | |
return atok_t_switch::ID; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('n', 0, 32) | onechar('a', 8, 32) | onechar('m', 16, 32) | onechar('e', 24, 32): | |
return atok_t_switch::NAME; | |
break; | |
case onechar('t', 0, 32) | onechar('y', 8, 32) | onechar('p', 16, 32) | onechar('e', 24, 32): | |
return atok_t_switch::TYPE; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <switch>."); | |
} | |
inline atok_t_segment_timing lex_attr_t_segment_timing(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 11: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('C', 0, 64) | onechar('_', 8, 64) | onechar('p', 16, 64) | onechar('e', 24, 64) | onechar('r', 32, 64) | onechar('_', 40, 64) | onechar('m', 48, 64) | onechar('e', 56, 64): | |
switch(in[8]){ | |
case onechar('t', 0, 8): | |
switch(in[9]){ | |
case onechar('e', 0, 8): | |
switch(in[10]){ | |
case onechar('r', 0, 8): | |
return atok_t_segment_timing::C_PER_METER; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case onechar('R', 0, 64) | onechar('_', 8, 64) | onechar('p', 16, 64) | onechar('e', 24, 64) | onechar('r', 32, 64) | onechar('_', 40, 64) | onechar('m', 48, 64) | onechar('e', 56, 64): | |
switch(in[8]){ | |
case onechar('t', 0, 8): | |
switch(in[9]){ | |
case onechar('e', 0, 8): | |
switch(in[10]){ | |
case onechar('r', 0, 8): | |
return atok_t_segment_timing::R_PER_METER; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <segment_timing>."); | |
} | |
inline gtok_t_segment lex_node_t_segment(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 6: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('t', 0, 32) | onechar('i', 8, 32) | onechar('m', 16, 32) | onechar('i', 24, 32): | |
switch(in[4]){ | |
case onechar('n', 0, 8): | |
switch(in[5]){ | |
case onechar('g', 0, 8): | |
return gtok_t_segment::TIMING; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <segment>."); | |
} | |
inline atok_t_segment lex_attr_t_segment(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 2: | |
switch(in[0]){ | |
case onechar('i', 0, 8): | |
switch(in[1]){ | |
case onechar('d', 0, 8): | |
return atok_t_segment::ID; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('n', 0, 32) | onechar('a', 8, 32) | onechar('m', 16, 32) | onechar('e', 24, 32): | |
return atok_t_segment::NAME; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <segment>."); | |
} | |
inline atok_t_pin lex_attr_t_pin(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 3: | |
switch(in[0]){ | |
case onechar('p', 0, 8): | |
switch(in[1]){ | |
case onechar('t', 0, 8): | |
switch(in[2]){ | |
case onechar('c', 0, 8): | |
return atok_t_pin::PTC; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <pin>."); | |
} | |
inline gtok_t_pin_class lex_node_t_pin_class(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 3: | |
switch(in[0]){ | |
case onechar('p', 0, 8): | |
switch(in[1]){ | |
case onechar('i', 0, 8): | |
switch(in[2]){ | |
case onechar('n', 0, 8): | |
return gtok_t_pin_class::PIN; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <pin_class>."); | |
} | |
inline atok_t_pin_class lex_attr_t_pin_class(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('t', 0, 32) | onechar('y', 8, 32) | onechar('p', 16, 32) | onechar('e', 24, 32): | |
return atok_t_pin_class::TYPE; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <pin_class>."); | |
} | |
inline atok_t_meta lex_attr_t_meta(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('n', 0, 32) | onechar('a', 8, 32) | onechar('m', 16, 32) | onechar('e', 24, 32): | |
return atok_t_meta::NAME; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <meta>."); | |
} | |
inline gtok_t_metadata lex_node_t_metadata(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('m', 0, 32) | onechar('e', 8, 32) | onechar('t', 16, 32) | onechar('a', 24, 32): | |
return gtok_t_metadata::META; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <metadata>."); | |
} | |
inline gtok_t_block_type lex_node_t_block_type(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 9: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('p', 0, 64) | onechar('i', 8, 64) | onechar('n', 16, 64) | onechar('_', 24, 64) | onechar('c', 32, 64) | onechar('l', 40, 64) | onechar('a', 48, 64) | onechar('s', 56, 64): | |
switch(in[8]){ | |
case onechar('s', 0, 8): | |
return gtok_t_block_type::PIN_CLASS; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <block_type>."); | |
} | |
inline atok_t_block_type lex_attr_t_block_type(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 2: | |
switch(in[0]){ | |
case onechar('i', 0, 8): | |
switch(in[1]){ | |
case onechar('d', 0, 8): | |
return atok_t_block_type::ID; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('n', 0, 32) | onechar('a', 8, 32) | onechar('m', 16, 32) | onechar('e', 24, 32): | |
return atok_t_block_type::NAME; | |
break; | |
default: break; | |
} | |
break; | |
case 5: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('w', 0, 32) | onechar('i', 8, 32) | onechar('d', 16, 32) | onechar('t', 24, 32): | |
switch(in[4]){ | |
case onechar('h', 0, 8): | |
return atok_t_block_type::WIDTH; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 6: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('h', 0, 32) | onechar('e', 8, 32) | onechar('i', 16, 32) | onechar('g', 24, 32): | |
switch(in[4]){ | |
case onechar('h', 0, 8): | |
switch(in[5]){ | |
case onechar('t', 0, 8): | |
return atok_t_block_type::HEIGHT; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <block_type>."); | |
} | |
inline atok_t_grid_loc lex_attr_t_grid_loc(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 1: | |
switch(in[0]){ | |
case onechar('x', 0, 8): | |
return atok_t_grid_loc::X; | |
break; | |
case onechar('y', 0, 8): | |
return atok_t_grid_loc::Y; | |
break; | |
default: break; | |
} | |
break; | |
case 12: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('w', 0, 64) | onechar('i', 8, 64) | onechar('d', 16, 64) | onechar('t', 24, 64) | onechar('h', 32, 64) | onechar('_', 40, 64) | onechar('o', 48, 64) | onechar('f', 56, 64): | |
switch(*((triehash_uu32*)&in[8])){ | |
case onechar('f', 0, 32) | onechar('s', 8, 32) | onechar('e', 16, 32) | onechar('t', 24, 32): | |
return atok_t_grid_loc::WIDTH_OFFSET; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 13: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('b', 0, 64) | onechar('l', 8, 64) | onechar('o', 16, 64) | onechar('c', 24, 64) | onechar('k', 32, 64) | onechar('_', 40, 64) | onechar('t', 48, 64) | onechar('y', 56, 64): | |
switch(*((triehash_uu32*)&in[8])){ | |
case onechar('p', 0, 32) | onechar('e', 8, 32) | onechar('_', 16, 32) | onechar('i', 24, 32): | |
switch(in[12]){ | |
case onechar('d', 0, 8): | |
return atok_t_grid_loc::BLOCK_TYPE_ID; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case onechar('h', 0, 64) | onechar('e', 8, 64) | onechar('i', 16, 64) | onechar('g', 24, 64) | onechar('h', 32, 64) | onechar('t', 40, 64) | onechar('_', 48, 64) | onechar('o', 56, 64): | |
switch(*((triehash_uu32*)&in[8])){ | |
case onechar('f', 0, 32) | onechar('f', 8, 32) | onechar('s', 16, 32) | onechar('e', 24, 32): | |
switch(in[12]){ | |
case onechar('t', 0, 8): | |
return atok_t_grid_loc::HEIGHT_OFFSET; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <grid_loc>."); | |
} | |
inline atok_t_node_loc lex_attr_t_node_loc(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 3: | |
switch(in[0]){ | |
case onechar('p', 0, 8): | |
switch(in[1]){ | |
case onechar('t', 0, 8): | |
switch(in[2]){ | |
case onechar('c', 0, 8): | |
return atok_t_node_loc::PTC; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('s', 0, 32) | onechar('i', 8, 32) | onechar('d', 16, 32) | onechar('e', 24, 32): | |
return atok_t_node_loc::SIDE; | |
break; | |
case onechar('x', 0, 32) | onechar('l', 8, 32) | onechar('o', 16, 32) | onechar('w', 24, 32): | |
return atok_t_node_loc::XLOW; | |
break; | |
case onechar('y', 0, 32) | onechar('l', 8, 32) | onechar('o', 16, 32) | onechar('w', 24, 32): | |
return atok_t_node_loc::YLOW; | |
break; | |
default: break; | |
} | |
break; | |
case 5: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('x', 0, 32) | onechar('h', 8, 32) | onechar('i', 16, 32) | onechar('g', 24, 32): | |
switch(in[4]){ | |
case onechar('h', 0, 8): | |
return atok_t_node_loc::XHIGH; | |
break; | |
default: break; | |
} | |
break; | |
case onechar('y', 0, 32) | onechar('h', 8, 32) | onechar('i', 16, 32) | onechar('g', 24, 32): | |
switch(in[4]){ | |
case onechar('h', 0, 8): | |
return atok_t_node_loc::YHIGH; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <node_loc>."); | |
} | |
inline atok_t_node_timing lex_attr_t_node_timing(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 1: | |
switch(in[0]){ | |
case onechar('C', 0, 8): | |
return atok_t_node_timing::C; | |
break; | |
case onechar('R', 0, 8): | |
return atok_t_node_timing::R; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <node_timing>."); | |
} | |
inline atok_t_node_segment lex_attr_t_node_segment(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 10: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('s', 0, 64) | onechar('e', 8, 64) | onechar('g', 16, 64) | onechar('m', 24, 64) | onechar('e', 32, 64) | onechar('n', 40, 64) | onechar('t', 48, 64) | onechar('_', 56, 64): | |
switch(in[8]){ | |
case onechar('i', 0, 8): | |
switch(in[9]){ | |
case onechar('d', 0, 8): | |
return atok_t_node_segment::SEGMENT_ID; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <node_segment>."); | |
} | |
inline atok_t_node_connection_box lex_attr_t_node_connection_box(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 1: | |
switch(in[0]){ | |
case onechar('x', 0, 8): | |
return atok_t_node_connection_box::X; | |
break; | |
case onechar('y', 0, 8): | |
return atok_t_node_connection_box::Y; | |
break; | |
default: break; | |
} | |
break; | |
case 2: | |
switch(in[0]){ | |
case onechar('i', 0, 8): | |
switch(in[1]){ | |
case onechar('d', 0, 8): | |
return atok_t_node_connection_box::ID; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <node_connection_box>."); | |
} | |
inline atok_t_node_canonical_loc lex_attr_t_node_canonical_loc(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 1: | |
switch(in[0]){ | |
case onechar('x', 0, 8): | |
return atok_t_node_canonical_loc::X; | |
break; | |
case onechar('y', 0, 8): | |
return atok_t_node_canonical_loc::Y; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <node_canonical_loc>."); | |
} | |
inline gtok_t_node lex_node_t_node(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 3: | |
switch(in[0]){ | |
case onechar('l', 0, 8): | |
switch(in[1]){ | |
case onechar('o', 0, 8): | |
switch(in[2]){ | |
case onechar('c', 0, 8): | |
return gtok_t_node::LOC; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 6: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('t', 0, 32) | onechar('i', 8, 32) | onechar('m', 16, 32) | onechar('i', 24, 32): | |
switch(in[4]){ | |
case onechar('n', 0, 8): | |
switch(in[5]){ | |
case onechar('g', 0, 8): | |
return gtok_t_node::TIMING; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 7: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('s', 0, 32) | onechar('e', 8, 32) | onechar('g', 16, 32) | onechar('m', 24, 32): | |
switch(in[4]){ | |
case onechar('e', 0, 8): | |
switch(in[5]){ | |
case onechar('n', 0, 8): | |
switch(in[6]){ | |
case onechar('t', 0, 8): | |
return gtok_t_node::SEGMENT; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 8: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('m', 0, 64) | onechar('e', 8, 64) | onechar('t', 16, 64) | onechar('a', 24, 64) | onechar('d', 32, 64) | onechar('a', 40, 64) | onechar('t', 48, 64) | onechar('a', 56, 64): | |
return gtok_t_node::METADATA; | |
break; | |
default: break; | |
} | |
break; | |
case 13: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('c', 0, 64) | onechar('a', 8, 64) | onechar('n', 16, 64) | onechar('o', 24, 64) | onechar('n', 32, 64) | onechar('i', 40, 64) | onechar('c', 48, 64) | onechar('a', 56, 64): | |
switch(*((triehash_uu32*)&in[8])){ | |
case onechar('l', 0, 32) | onechar('_', 8, 32) | onechar('l', 16, 32) | onechar('o', 24, 32): | |
switch(in[12]){ | |
case onechar('c', 0, 8): | |
return gtok_t_node::CANONICAL_LOC; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 14: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('c', 0, 64) | onechar('o', 8, 64) | onechar('n', 16, 64) | onechar('n', 24, 64) | onechar('e', 32, 64) | onechar('c', 40, 64) | onechar('t', 48, 64) | onechar('i', 56, 64): | |
switch(*((triehash_uu32*)&in[8])){ | |
case onechar('o', 0, 32) | onechar('n', 8, 32) | onechar('_', 16, 32) | onechar('b', 24, 32): | |
switch(in[12]){ | |
case onechar('o', 0, 8): | |
switch(in[13]){ | |
case onechar('x', 0, 8): | |
return gtok_t_node::CONNECTION_BOX; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <node>."); | |
} | |
inline atok_t_node lex_attr_t_node(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 2: | |
switch(in[0]){ | |
case onechar('i', 0, 8): | |
switch(in[1]){ | |
case onechar('d', 0, 8): | |
return atok_t_node::ID; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('t', 0, 32) | onechar('y', 8, 32) | onechar('p', 16, 32) | onechar('e', 24, 32): | |
return atok_t_node::TYPE; | |
break; | |
default: break; | |
} | |
break; | |
case 8: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('c', 0, 64) | onechar('a', 8, 64) | onechar('p', 16, 64) | onechar('a', 24, 64) | onechar('c', 32, 64) | onechar('i', 40, 64) | onechar('t', 48, 64) | onechar('y', 56, 64): | |
return atok_t_node::CAPACITY; | |
break; | |
default: break; | |
} | |
break; | |
case 9: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('d', 0, 64) | onechar('i', 8, 64) | onechar('r', 16, 64) | onechar('e', 24, 64) | onechar('c', 32, 64) | onechar('t', 40, 64) | onechar('i', 48, 64) | onechar('o', 56, 64): | |
switch(in[8]){ | |
case onechar('n', 0, 8): | |
return atok_t_node::DIRECTION; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <node>."); | |
} | |
inline gtok_t_edge lex_node_t_edge(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 8: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('m', 0, 64) | onechar('e', 8, 64) | onechar('t', 16, 64) | onechar('a', 24, 64) | onechar('d', 32, 64) | onechar('a', 40, 64) | onechar('t', 48, 64) | onechar('a', 56, 64): | |
return gtok_t_edge::METADATA; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <edge>."); | |
} | |
inline atok_t_edge lex_attr_t_edge(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 2: | |
switch(in[0]){ | |
case onechar('i', 0, 8): | |
switch(in[1]){ | |
case onechar('d', 0, 8): | |
return atok_t_edge::ID; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 8: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('s', 0, 64) | onechar('r', 8, 64) | onechar('c', 16, 64) | onechar('_', 24, 64) | onechar('n', 32, 64) | onechar('o', 40, 64) | onechar('d', 48, 64) | onechar('e', 56, 64): | |
return atok_t_edge::SRC_NODE; | |
break; | |
default: break; | |
} | |
break; | |
case 9: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('s', 0, 64) | onechar('i', 8, 64) | onechar('n', 16, 64) | onechar('k', 24, 64) | onechar('_', 32, 64) | onechar('n', 40, 64) | onechar('o', 48, 64) | onechar('d', 56, 64): | |
switch(in[8]){ | |
case onechar('e', 0, 8): | |
return atok_t_edge::SINK_NODE; | |
break; | |
default: break; | |
} | |
break; | |
case onechar('s', 0, 64) | onechar('w', 8, 64) | onechar('i', 16, 64) | onechar('t', 24, 64) | onechar('c', 32, 64) | onechar('h', 40, 64) | onechar('_', 48, 64) | onechar('i', 56, 64): | |
switch(in[8]){ | |
case onechar('d', 0, 8): | |
return atok_t_edge::SWITCH_ID; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <edge>."); | |
} | |
inline gtok_t_channels lex_node_t_channels(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 6: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('x', 0, 32) | onechar('_', 8, 32) | onechar('l', 16, 32) | onechar('i', 24, 32): | |
switch(in[4]){ | |
case onechar('s', 0, 8): | |
switch(in[5]){ | |
case onechar('t', 0, 8): | |
return gtok_t_channels::X_LIST; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case onechar('y', 0, 32) | onechar('_', 8, 32) | onechar('l', 16, 32) | onechar('i', 24, 32): | |
switch(in[4]){ | |
case onechar('s', 0, 8): | |
switch(in[5]){ | |
case onechar('t', 0, 8): | |
return gtok_t_channels::Y_LIST; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 7: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('c', 0, 32) | onechar('h', 8, 32) | onechar('a', 16, 32) | onechar('n', 24, 32): | |
switch(in[4]){ | |
case onechar('n', 0, 8): | |
switch(in[5]){ | |
case onechar('e', 0, 8): | |
switch(in[6]){ | |
case onechar('l', 0, 8): | |
return gtok_t_channels::CHANNEL; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <channels>."); | |
} | |
inline gtok_t_switches lex_node_t_switches(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 6: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('s', 0, 32) | onechar('w', 8, 32) | onechar('i', 16, 32) | onechar('t', 24, 32): | |
switch(in[4]){ | |
case onechar('c', 0, 8): | |
switch(in[5]){ | |
case onechar('h', 0, 8): | |
return gtok_t_switches::SWITCH; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <switches>."); | |
} | |
inline gtok_t_segments lex_node_t_segments(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 7: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('s', 0, 32) | onechar('e', 8, 32) | onechar('g', 16, 32) | onechar('m', 24, 32): | |
switch(in[4]){ | |
case onechar('e', 0, 8): | |
switch(in[5]){ | |
case onechar('n', 0, 8): | |
switch(in[6]){ | |
case onechar('t', 0, 8): | |
return gtok_t_segments::SEGMENT; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <segments>."); | |
} | |
inline gtok_t_block_types lex_node_t_block_types(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 10: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('b', 0, 64) | onechar('l', 8, 64) | onechar('o', 16, 64) | onechar('c', 24, 64) | onechar('k', 32, 64) | onechar('_', 40, 64) | onechar('t', 48, 64) | onechar('y', 56, 64): | |
switch(in[8]){ | |
case onechar('p', 0, 8): | |
switch(in[9]){ | |
case onechar('e', 0, 8): | |
return gtok_t_block_types::BLOCK_TYPE; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <block_types>."); | |
} | |
inline gtok_t_grid_locs lex_node_t_grid_locs(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 8: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('g', 0, 64) | onechar('r', 8, 64) | onechar('i', 16, 64) | onechar('d', 24, 64) | onechar('_', 32, 64) | onechar('l', 40, 64) | onechar('o', 48, 64) | onechar('c', 56, 64): | |
return gtok_t_grid_locs::GRID_LOC; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <grid_locs>."); | |
} | |
inline gtok_t_rr_nodes lex_node_t_rr_nodes(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('n', 0, 32) | onechar('o', 8, 32) | onechar('d', 16, 32) | onechar('e', 24, 32): | |
return gtok_t_rr_nodes::NODE; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <rr_nodes>."); | |
} | |
inline gtok_t_rr_edges lex_node_t_rr_edges(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('e', 0, 32) | onechar('d', 8, 32) | onechar('g', 16, 32) | onechar('e', 24, 32): | |
return gtok_t_rr_edges::EDGE; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <rr_edges>."); | |
} | |
inline atok_t_bin_nodes lex_attr_t_bin_nodes(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('f', 0, 32) | onechar('i', 8, 32) | onechar('l', 16, 32) | onechar('e', 24, 32): | |
return atok_t_bin_nodes::FILE; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <bin_nodes>."); | |
} | |
inline atok_t_connection_box lex_attr_t_connection_box(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 2: | |
switch(in[0]){ | |
case onechar('i', 0, 8): | |
switch(in[1]){ | |
case onechar('d', 0, 8): | |
return atok_t_connection_box::ID; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('n', 0, 32) | onechar('a', 8, 32) | onechar('m', 16, 32) | onechar('e', 24, 32): | |
return atok_t_connection_box::NAME; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <connection_box>."); | |
} | |
inline gtok_t_connection_boxes lex_node_t_connection_boxes(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 14: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('c', 0, 64) | onechar('o', 8, 64) | onechar('n', 16, 64) | onechar('n', 24, 64) | onechar('e', 32, 64) | onechar('c', 40, 64) | onechar('t', 48, 64) | onechar('i', 56, 64): | |
switch(*((triehash_uu32*)&in[8])){ | |
case onechar('o', 0, 32) | onechar('n', 8, 32) | onechar('_', 16, 32) | onechar('b', 24, 32): | |
switch(in[12]){ | |
case onechar('o', 0, 8): | |
switch(in[13]){ | |
case onechar('x', 0, 8): | |
return gtok_t_connection_boxes::CONNECTION_BOX; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <connection_boxes>."); | |
} | |
inline atok_t_connection_boxes lex_attr_t_connection_boxes(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 5: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('x', 0, 32) | onechar('_', 8, 32) | onechar('d', 16, 32) | onechar('i', 24, 32): | |
switch(in[4]){ | |
case onechar('m', 0, 8): | |
return atok_t_connection_boxes::X_DIM; | |
break; | |
default: break; | |
} | |
break; | |
case onechar('y', 0, 32) | onechar('_', 8, 32) | onechar('d', 16, 32) | onechar('i', 24, 32): | |
switch(in[4]){ | |
case onechar('m', 0, 8): | |
return atok_t_connection_boxes::Y_DIM; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 9: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('n', 0, 64) | onechar('u', 8, 64) | onechar('m', 16, 64) | onechar('_', 24, 64) | onechar('b', 32, 64) | onechar('o', 40, 64) | onechar('x', 48, 64) | onechar('e', 56, 64): | |
switch(in[8]){ | |
case onechar('s', 0, 8): | |
return atok_t_connection_boxes::NUM_BOXES; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <connection_boxes>."); | |
} | |
inline gtok_t_rr_graph lex_node_t_rr_graph(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('g', 0, 32) | onechar('r', 8, 32) | onechar('i', 16, 32) | onechar('d', 24, 32): | |
return gtok_t_rr_graph::GRID; | |
break; | |
default: break; | |
} | |
break; | |
case 8: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('c', 0, 64) | onechar('h', 8, 64) | onechar('a', 16, 64) | onechar('n', 24, 64) | onechar('n', 32, 64) | onechar('e', 40, 64) | onechar('l', 48, 64) | onechar('s', 56, 64): | |
return gtok_t_rr_graph::CHANNELS; | |
break; | |
case onechar('r', 0, 64) | onechar('r', 8, 64) | onechar('_', 16, 64) | onechar('e', 24, 64) | onechar('d', 32, 64) | onechar('g', 40, 64) | onechar('e', 48, 64) | onechar('s', 56, 64): | |
return gtok_t_rr_graph::RR_EDGES; | |
break; | |
case onechar('r', 0, 64) | onechar('r', 8, 64) | onechar('_', 16, 64) | onechar('n', 24, 64) | onechar('o', 32, 64) | onechar('d', 40, 64) | onechar('e', 48, 64) | onechar('s', 56, 64): | |
return gtok_t_rr_graph::RR_NODES; | |
break; | |
case onechar('s', 0, 64) | onechar('e', 8, 64) | onechar('g', 16, 64) | onechar('m', 24, 64) | onechar('e', 32, 64) | onechar('n', 40, 64) | onechar('t', 48, 64) | onechar('s', 56, 64): | |
return gtok_t_rr_graph::SEGMENTS; | |
break; | |
case onechar('s', 0, 64) | onechar('w', 8, 64) | onechar('i', 16, 64) | onechar('t', 24, 64) | onechar('c', 32, 64) | onechar('h', 40, 64) | onechar('e', 48, 64) | onechar('s', 56, 64): | |
return gtok_t_rr_graph::SWITCHES; | |
break; | |
default: break; | |
} | |
break; | |
case 11: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('b', 0, 64) | onechar('l', 8, 64) | onechar('o', 16, 64) | onechar('c', 24, 64) | onechar('k', 32, 64) | onechar('_', 40, 64) | onechar('t', 48, 64) | onechar('y', 56, 64): | |
switch(in[8]){ | |
case onechar('p', 0, 8): | |
switch(in[9]){ | |
case onechar('e', 0, 8): | |
switch(in[10]){ | |
case onechar('s', 0, 8): | |
return gtok_t_rr_graph::BLOCK_TYPES; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 16: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('c', 0, 64) | onechar('o', 8, 64) | onechar('n', 16, 64) | onechar('n', 24, 64) | onechar('e', 32, 64) | onechar('c', 40, 64) | onechar('t', 48, 64) | onechar('i', 56, 64): | |
switch(*((triehash_uu64*)&in[8])){ | |
case onechar('o', 0, 64) | onechar('n', 8, 64) | onechar('_', 16, 64) | onechar('b', 24, 64) | onechar('o', 32, 64) | onechar('x', 40, 64) | onechar('e', 48, 64) | onechar('s', 56, 64): | |
return gtok_t_rr_graph::CONNECTION_BOXES; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 22: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('b', 0, 64) | onechar('i', 8, 64) | onechar('n', 16, 64) | onechar('a', 24, 64) | onechar('r', 32, 64) | onechar('y', 40, 64) | onechar('_', 48, 64) | onechar('n', 56, 64): | |
switch(*((triehash_uu64*)&in[8])){ | |
case onechar('o', 0, 64) | onechar('d', 8, 64) | onechar('e', 16, 64) | onechar('s', 24, 64) | onechar('_', 32, 64) | onechar('a', 40, 64) | onechar('n', 48, 64) | onechar('d', 56, 64): | |
switch(*((triehash_uu32*)&in[16])){ | |
case onechar('_', 0, 32) | onechar('e', 8, 32) | onechar('d', 16, 32) | onechar('g', 24, 32): | |
switch(in[20]){ | |
case onechar('e', 0, 8): | |
switch(in[21]){ | |
case onechar('s', 0, 8): | |
return gtok_t_rr_graph::BINARY_NODES_AND_EDGES; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized child " + std::string(in) + " of <rr_graph>."); | |
} | |
inline atok_t_rr_graph lex_attr_t_rr_graph(const char *in){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 9: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('t', 0, 64) | onechar('o', 8, 64) | onechar('o', 16, 64) | onechar('l', 24, 64) | onechar('_', 32, 64) | onechar('n', 40, 64) | onechar('a', 48, 64) | onechar('m', 56, 64): | |
switch(in[8]){ | |
case onechar('e', 0, 8): | |
return atok_t_rr_graph::TOOL_NAME; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 12: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('t', 0, 64) | onechar('o', 8, 64) | onechar('o', 16, 64) | onechar('l', 24, 64) | onechar('_', 32, 64) | onechar('c', 40, 64) | onechar('o', 48, 64) | onechar('m', 56, 64): | |
switch(*((triehash_uu32*)&in[8])){ | |
case onechar('m', 0, 32) | onechar('e', 8, 32) | onechar('n', 16, 32) | onechar('t', 24, 32): | |
return atok_t_rr_graph::TOOL_COMMENT; | |
break; | |
default: break; | |
} | |
break; | |
case onechar('t', 0, 64) | onechar('o', 8, 64) | onechar('o', 16, 64) | onechar('l', 24, 64) | onechar('_', 32, 64) | onechar('v', 40, 64) | onechar('e', 48, 64) | onechar('r', 56, 64): | |
switch(*((triehash_uu32*)&in[8])){ | |
case onechar('s', 0, 32) | onechar('i', 8, 32) | onechar('o', 16, 32) | onechar('n', 24, 32): | |
return atok_t_rr_graph::TOOL_VERSION; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
throw std::runtime_error("Found unrecognized attribute " + std::string(in) + " of <rr_graph>."); | |
} | |
/** | |
* Internal error function for xs:choice and xs:sequence validators. | |
*/ | |
inline void dfa_error(const char *wrong, int *states, const char **lookup, int len); | |
/** | |
* Internal error function for xs:all validators. | |
*/ | |
template<std::size_t N> | |
inline void all_error(std::bitset<N> gstate, const char **lookup); | |
/** | |
* Internal error function for attribute validators. | |
*/ | |
template<std::size_t N> | |
inline void attr_error(std::bitset<N> astate, const char **lookup); | |
/* Lookup tables for enums. */ | |
const char *lookup_switch_type[] = {"UXSD_INVALID", "mux", "tristate", "pass_gate", "short", "buffer"}; | |
const char *lookup_pin_type[] = {"UXSD_INVALID", "OPEN", "OUTPUT", "INPUT"}; | |
const char *lookup_loc_side[] = {"UXSD_INVALID", "LEFT", "RIGHT", "TOP", "BOTTOM"}; | |
const char *lookup_node_type[] = {"UXSD_INVALID", "CHANX", "CHANY", "SOURCE", "SINK", "OPIN", "IPIN"}; | |
const char *lookup_node_direction[] = {"UXSD_INVALID", "INC_DIR", "DEC_DIR", "BI_DIR"}; | |
/* Lexers(string->token functions) for enums. */ | |
inline enum_switch_type lex_enum_switch_type(const char *in, bool throw_on_invalid){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 3: | |
switch(in[0]){ | |
case onechar('m', 0, 8): | |
switch(in[1]){ | |
case onechar('u', 0, 8): | |
switch(in[2]){ | |
case onechar('x', 0, 8): | |
return enum_switch_type::MUX; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 5: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('s', 0, 32) | onechar('h', 8, 32) | onechar('o', 16, 32) | onechar('r', 24, 32): | |
switch(in[4]){ | |
case onechar('t', 0, 8): | |
return enum_switch_type::SHORT; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 6: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('b', 0, 32) | onechar('u', 8, 32) | onechar('f', 16, 32) | onechar('f', 24, 32): | |
switch(in[4]){ | |
case onechar('e', 0, 8): | |
switch(in[5]){ | |
case onechar('r', 0, 8): | |
return enum_switch_type::BUFFER; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 8: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('t', 0, 64) | onechar('r', 8, 64) | onechar('i', 16, 64) | onechar('s', 24, 64) | onechar('t', 32, 64) | onechar('a', 40, 64) | onechar('t', 48, 64) | onechar('e', 56, 64): | |
return enum_switch_type::TRISTATE; | |
break; | |
default: break; | |
} | |
break; | |
case 9: | |
switch(*((triehash_uu64*)&in[0])){ | |
case onechar('p', 0, 64) | onechar('a', 8, 64) | onechar('s', 16, 64) | onechar('s', 24, 64) | onechar('_', 32, 64) | onechar('g', 40, 64) | onechar('a', 48, 64) | onechar('t', 56, 64): | |
switch(in[8]){ | |
case onechar('e', 0, 8): | |
return enum_switch_type::PASS_GATE; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
if(throw_on_invalid) | |
throw std::runtime_error("Found unrecognized enum value " + std::string(in) + " of enum_switch_type."); | |
return enum_switch_type::UXSD_INVALID; | |
} | |
inline enum_pin_type lex_enum_pin_type(const char *in, bool throw_on_invalid){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('O', 0, 32) | onechar('P', 8, 32) | onechar('E', 16, 32) | onechar('N', 24, 32): | |
return enum_pin_type::OPEN; | |
break; | |
default: break; | |
} | |
break; | |
case 5: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('I', 0, 32) | onechar('N', 8, 32) | onechar('P', 16, 32) | onechar('U', 24, 32): | |
switch(in[4]){ | |
case onechar('T', 0, 8): | |
return enum_pin_type::INPUT; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 6: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('O', 0, 32) | onechar('U', 8, 32) | onechar('T', 16, 32) | onechar('P', 24, 32): | |
switch(in[4]){ | |
case onechar('U', 0, 8): | |
switch(in[5]){ | |
case onechar('T', 0, 8): | |
return enum_pin_type::OUTPUT; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
if(throw_on_invalid) | |
throw std::runtime_error("Found unrecognized enum value " + std::string(in) + " of enum_pin_type."); | |
return enum_pin_type::UXSD_INVALID; | |
} | |
inline enum_loc_side lex_enum_loc_side(const char *in, bool throw_on_invalid){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 3: | |
switch(in[0]){ | |
case onechar('T', 0, 8): | |
switch(in[1]){ | |
case onechar('O', 0, 8): | |
switch(in[2]){ | |
case onechar('P', 0, 8): | |
return enum_loc_side::TOP; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('L', 0, 32) | onechar('E', 8, 32) | onechar('F', 16, 32) | onechar('T', 24, 32): | |
return enum_loc_side::LEFT; | |
break; | |
default: break; | |
} | |
break; | |
case 5: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('R', 0, 32) | onechar('I', 8, 32) | onechar('G', 16, 32) | onechar('H', 24, 32): | |
switch(in[4]){ | |
case onechar('T', 0, 8): | |
return enum_loc_side::RIGHT; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 6: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('B', 0, 32) | onechar('O', 8, 32) | onechar('T', 16, 32) | onechar('T', 24, 32): | |
switch(in[4]){ | |
case onechar('O', 0, 8): | |
switch(in[5]){ | |
case onechar('M', 0, 8): | |
return enum_loc_side::BOTTOM; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
if(throw_on_invalid) | |
throw std::runtime_error("Found unrecognized enum value " + std::string(in) + " of enum_loc_side."); | |
return enum_loc_side::UXSD_INVALID; | |
} | |
inline enum_node_type lex_enum_node_type(const char *in, bool throw_on_invalid){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 4: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('I', 0, 32) | onechar('P', 8, 32) | onechar('I', 16, 32) | onechar('N', 24, 32): | |
return enum_node_type::IPIN; | |
break; | |
case onechar('O', 0, 32) | onechar('P', 8, 32) | onechar('I', 16, 32) | onechar('N', 24, 32): | |
return enum_node_type::OPIN; | |
break; | |
case onechar('S', 0, 32) | onechar('I', 8, 32) | onechar('N', 16, 32) | onechar('K', 24, 32): | |
return enum_node_type::SINK; | |
break; | |
default: break; | |
} | |
break; | |
case 5: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('C', 0, 32) | onechar('H', 8, 32) | onechar('A', 16, 32) | onechar('N', 24, 32): | |
switch(in[4]){ | |
case onechar('X', 0, 8): | |
return enum_node_type::CHANX; | |
break; | |
case onechar('Y', 0, 8): | |
return enum_node_type::CHANY; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 6: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('S', 0, 32) | onechar('O', 8, 32) | onechar('U', 16, 32) | onechar('R', 24, 32): | |
switch(in[4]){ | |
case onechar('C', 0, 8): | |
switch(in[5]){ | |
case onechar('E', 0, 8): | |
return enum_node_type::SOURCE; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
if(throw_on_invalid) | |
throw std::runtime_error("Found unrecognized enum value " + std::string(in) + " of enum_node_type."); | |
return enum_node_type::UXSD_INVALID; | |
} | |
inline enum_node_direction lex_enum_node_direction(const char *in, bool throw_on_invalid){ | |
unsigned int len = strlen(in); | |
switch(len){ | |
case 6: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('B', 0, 32) | onechar('I', 8, 32) | onechar('_', 16, 32) | onechar('D', 24, 32): | |
switch(in[4]){ | |
case onechar('I', 0, 8): | |
switch(in[5]){ | |
case onechar('R', 0, 8): | |
return enum_node_direction::BI_DIR; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case 7: | |
switch(*((triehash_uu32*)&in[0])){ | |
case onechar('D', 0, 32) | onechar('E', 8, 32) | onechar('C', 16, 32) | onechar('_', 24, 32): | |
switch(in[4]){ | |
case onechar('D', 0, 8): | |
switch(in[5]){ | |
case onechar('I', 0, 8): | |
switch(in[6]){ | |
case onechar('R', 0, 8): | |
return enum_node_direction::DEC_DIR; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
case onechar('I', 0, 32) | onechar('N', 8, 32) | onechar('C', 16, 32) | onechar('_', 24, 32): | |
switch(in[4]){ | |
case onechar('D', 0, 8): | |
switch(in[5]){ | |
case onechar('I', 0, 8): | |
switch(in[6]){ | |
case onechar('R', 0, 8): | |
return enum_node_direction::INC_DIR; | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
break; | |
default: break; | |
} | |
if(throw_on_invalid) | |
throw std::runtime_error("Found unrecognized enum value " + std::string(in) + " of enum_node_direction."); | |
return enum_node_direction::UXSD_INVALID; | |
} | |
/* Internal loading functions, which validate and load a PugiXML DOM tree into memory. */ | |
inline int load_int(const char *in){ | |
int out; | |
out = std::strtol(in, NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(in) + "` when loading into a int."); return out; | |
} | |
inline unsigned int load_unsigned_int(const char *in){ | |
unsigned int out; | |
out = std::strtoul(in, NULL, 10); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(in) + "` when loading into a unsigned int."); return out; | |
} | |
inline float load_float(const char *in){ | |
float out; | |
out = std::strtof(in, NULL); | |
if(errno != 0) | |
throw std::runtime_error("Invalid value `" + std::string(in) + "` when loading into a float."); return out; | |
} | |
template<class T> | |
void load_channel(const pugi::xml_node &root, T &out, void *data){ | |
if(root.first_child().type() == pugi::node_element) | |
throw std::runtime_error("Unexpected child element in <channel>."); | |
std::bitset<5> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_channel in = lex_attr_t_channel(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <channel>."); | |
switch(in){ | |
case atok_t_channel::CHAN_WIDTH_MAX: | |
out.set_channel_chan_width_max(load_int(attr.value()), data); | |
break; | |
case atok_t_channel::X_MAX: | |
out.set_channel_x_max(load_int(attr.value()), data); | |
break; | |
case atok_t_channel::X_MIN: | |
out.set_channel_x_min(load_int(attr.value()), data); | |
break; | |
case atok_t_channel::Y_MAX: | |
out.set_channel_y_max(load_int(attr.value()), data); | |
break; | |
case atok_t_channel::Y_MIN: | |
out.set_channel_y_min(load_int(attr.value()), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<5> test_astate = astate | std::bitset<5>(0b00000); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_channel); | |
} | |
template<class T> | |
void load_x_list(const pugi::xml_node &root, T &out, void *data){ | |
if(root.first_child().type() == pugi::node_element) | |
throw std::runtime_error("Unexpected child element in <x_list>."); | |
std::bitset<2> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_x_list in = lex_attr_t_x_list(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <x_list>."); | |
switch(in){ | |
case atok_t_x_list::INDEX: | |
out.set_x_list_index(load_unsigned_int(attr.value()), data); | |
break; | |
case atok_t_x_list::INFO: | |
out.set_x_list_info(load_int(attr.value()), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<2> test_astate = astate | std::bitset<2>(0b00); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_x_list); | |
} | |
template<class T> | |
void load_y_list(const pugi::xml_node &root, T &out, void *data){ | |
if(root.first_child().type() == pugi::node_element) | |
throw std::runtime_error("Unexpected child element in <y_list>."); | |
std::bitset<2> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_y_list in = lex_attr_t_y_list(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <y_list>."); | |
switch(in){ | |
case atok_t_y_list::INDEX: | |
out.set_y_list_index(load_unsigned_int(attr.value()), data); | |
break; | |
case atok_t_y_list::INFO: | |
out.set_y_list_info(load_int(attr.value()), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<2> test_astate = astate | std::bitset<2>(0b00); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_y_list); | |
} | |
template<class T> | |
void load_timing(const pugi::xml_node &root, T &out, void *data){ | |
if(root.first_child().type() == pugi::node_element) | |
throw std::runtime_error("Unexpected child element in <timing>."); | |
std::bitset<5> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_timing in = lex_attr_t_timing(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <timing>."); | |
switch(in){ | |
case atok_t_timing::CIN: | |
out.set_timing_Cin(load_float(attr.value()), data); | |
break; | |
case atok_t_timing::CINTERNAL: | |
out.set_timing_Cinternal(load_float(attr.value()), data); | |
break; | |
case atok_t_timing::COUT: | |
out.set_timing_Cout(load_float(attr.value()), data); | |
break; | |
case atok_t_timing::R: | |
out.set_timing_R(load_float(attr.value()), data); | |
break; | |
case atok_t_timing::TDEL: | |
out.set_timing_Tdel(load_float(attr.value()), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<5> test_astate = astate | std::bitset<5>(0b00000); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_timing); | |
} | |
template<class T> | |
void load_sizing(const pugi::xml_node &root, T &out, void *data){ | |
if(root.first_child().type() == pugi::node_element) | |
throw std::runtime_error("Unexpected child element in <sizing>."); | |
std::bitset<2> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_sizing in = lex_attr_t_sizing(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <sizing>."); | |
switch(in){ | |
case atok_t_sizing::BUF_SIZE: | |
out.set_sizing_buf_size(load_float(attr.value()), data); | |
break; | |
case atok_t_sizing::MUX_TRANS_SIZE: | |
out.set_sizing_mux_trans_size(load_float(attr.value()), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<2> test_astate = astate | std::bitset<2>(0b00); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_sizing); | |
} | |
template<class T> | |
void load_switch(const pugi::xml_node &root, T &out, void *data){ | |
std::bitset<2> gstate = 0; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_switch in = lex_node_t_switch(node.name()); | |
if(gstate[(int)in] == 0) gstate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate element " + std::string(node.name()) + " in <switch>."); | |
switch(in){ | |
case gtok_t_switch::TIMING: | |
load_timing(node, out.init_switch_timing(data)); | |
break; | |
case gtok_t_switch::SIZING: | |
load_sizing(node, out.init_switch_sizing(data)); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<2> test_gstate = gstate | std::bitset<2>(0b01); | |
if(!test_gstate.all()) all_error(test_gstate, gtok_lookup_t_switch); | |
std::bitset<3> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_switch in = lex_attr_t_switch(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <switch>."); | |
switch(in){ | |
case atok_t_switch::ID: | |
out.set_switch_id(load_int(attr.value()), data); | |
break; | |
case atok_t_switch::NAME: | |
out.set_switch_name(attr.value(), data); | |
break; | |
case atok_t_switch::TYPE: | |
out.set_switch_type(lex_enum_switch_type(attr.value(), true), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<3> test_astate = astate | std::bitset<3>(0b100); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_switch); | |
} | |
template<class T> | |
void load_segment_timing(const pugi::xml_node &root, T &out, void *data){ | |
if(root.first_child().type() == pugi::node_element) | |
throw std::runtime_error("Unexpected child element in <segment_timing>."); | |
std::bitset<2> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_segment_timing in = lex_attr_t_segment_timing(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <segment_timing>."); | |
switch(in){ | |
case atok_t_segment_timing::C_PER_METER: | |
out.set_segment_timing_C_per_meter(load_float(attr.value()), data); | |
break; | |
case atok_t_segment_timing::R_PER_METER: | |
out.set_segment_timing_R_per_meter(load_float(attr.value()), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<2> test_astate = astate | std::bitset<2>(0b11); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_segment_timing); | |
} | |
template<class T> | |
void load_segment(const pugi::xml_node &root, T &out, void *data){ | |
std::bitset<1> gstate = 0; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_segment in = lex_node_t_segment(node.name()); | |
if(gstate[(int)in] == 0) gstate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate element " + std::string(node.name()) + " in <segment>."); | |
switch(in){ | |
case gtok_t_segment::TIMING: | |
load_segment_timing(node, out.init_segment_timing(data)); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<1> test_gstate = gstate | std::bitset<1>(0b1); | |
if(!test_gstate.all()) all_error(test_gstate, gtok_lookup_t_segment); | |
std::bitset<2> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_segment in = lex_attr_t_segment(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <segment>."); | |
switch(in){ | |
case atok_t_segment::ID: | |
out.set_segment_id(load_int(attr.value()), data); | |
break; | |
case atok_t_segment::NAME: | |
out.set_segment_name(attr.value(), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<2> test_astate = astate | std::bitset<2>(0b00); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_segment); | |
} | |
template<class T> | |
void load_pin(const pugi::xml_node &root, T &out, void *data){ | |
out.set_pin_value(root.child_value()); | |
if(root.first_child().type() == pugi::node_element) | |
throw std::runtime_error("Unexpected child element in <pin>."); | |
std::bitset<1> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_pin in = lex_attr_t_pin(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <pin>."); | |
switch(in){ | |
case atok_t_pin::PTC: | |
out.set_pin_ptc(load_int(attr.value()), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<1> test_astate = astate | std::bitset<1>(0b0); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_pin); | |
} | |
static const int NUM_T_PIN_CLASS_STATES = 2; | |
static const int NUM_T_PIN_CLASS_INPUTS = 1; | |
static int gstate_t_pin_class[NUM_T_PIN_CLASS_STATES][NUM_T_PIN_CLASS_INPUTS] = { | |
{0}, | |
{0}, | |
}; | |
template<class T> | |
void load_pin_class(const pugi::xml_node &root, T &out, void *data){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_pin_class in = lex_node_t_pin_class(node.name()); | |
next = gstate_t_pin_class[state][(int)in]; | |
if(next == -1) | |
dfa_error(gtok_lookup_t_pin_class[(int)in], gstate_t_pin_class[state], gtok_lookup_t_pin_class, 1); | |
state = next; | |
switch(in){ | |
case gtok_t_pin_class::PIN: | |
load_pin(node, out.add_pin_class_pin(data)); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_pin_class[state], gtok_lookup_t_pin_class, 1); | |
std::bitset<1> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_pin_class in = lex_attr_t_pin_class(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <pin_class>."); | |
switch(in){ | |
case atok_t_pin_class::TYPE: | |
out.set_pin_class_type(lex_enum_pin_type(attr.value(), true), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<1> test_astate = astate | std::bitset<1>(0b0); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_pin_class); | |
} | |
template<class T> | |
void load_meta(const pugi::xml_node &root, T &out, void *data){ | |
out.set_meta_value(root.child_value()); | |
if(root.first_child().type() == pugi::node_element) | |
throw std::runtime_error("Unexpected child element in <meta>."); | |
std::bitset<1> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_meta in = lex_attr_t_meta(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <meta>."); | |
switch(in){ | |
case atok_t_meta::NAME: | |
out.set_meta_name(attr.value(), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<1> test_astate = astate | std::bitset<1>(0b0); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_meta); | |
} | |
static const int NUM_T_METADATA_STATES = 2; | |
static const int NUM_T_METADATA_INPUTS = 1; | |
static int gstate_t_metadata[NUM_T_METADATA_STATES][NUM_T_METADATA_INPUTS] = { | |
{0}, | |
{0}, | |
}; | |
template<class T> | |
void load_metadata(const pugi::xml_node &root, T &out, void *data){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_metadata in = lex_node_t_metadata(node.name()); | |
next = gstate_t_metadata[state][(int)in]; | |
if(next == -1) | |
dfa_error(gtok_lookup_t_metadata[(int)in], gstate_t_metadata[state], gtok_lookup_t_metadata, 1); | |
state = next; | |
switch(in){ | |
case gtok_t_metadata::META: | |
load_meta(node, out.add_metadata_meta(data)); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_metadata[state], gtok_lookup_t_metadata, 1); | |
if(root.first_attribute()) | |
throw std::runtime_error("Unexpected attribute in <metadata>."); | |
} | |
static const int NUM_T_BLOCK_TYPE_STATES = 1; | |
static const int NUM_T_BLOCK_TYPE_INPUTS = 1; | |
static int gstate_t_block_type[NUM_T_BLOCK_TYPE_STATES][NUM_T_BLOCK_TYPE_INPUTS] = { | |
{0}, | |
}; | |
template<class T> | |
void load_block_type(const pugi::xml_node &root, T &out, void *data){ | |
int next, state=0; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_block_type in = lex_node_t_block_type(node.name()); | |
next = gstate_t_block_type[state][(int)in]; | |
if(next == -1) | |
dfa_error(gtok_lookup_t_block_type[(int)in], gstate_t_block_type[state], gtok_lookup_t_block_type, 1); | |
state = next; | |
switch(in){ | |
case gtok_t_block_type::PIN_CLASS: | |
load_pin_class(node, out.add_block_type_pin_class(data)); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_block_type[state], gtok_lookup_t_block_type, 1); | |
std::bitset<4> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_block_type in = lex_attr_t_block_type(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <block_type>."); | |
switch(in){ | |
case atok_t_block_type::HEIGHT: | |
out.set_block_type_height(load_int(attr.value()), data); | |
break; | |
case atok_t_block_type::ID: | |
out.set_block_type_id(load_int(attr.value()), data); | |
break; | |
case atok_t_block_type::NAME: | |
out.set_block_type_name(attr.value(), data); | |
break; | |
case atok_t_block_type::WIDTH: | |
out.set_block_type_width(load_int(attr.value()), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<4> test_astate = astate | std::bitset<4>(0b0000); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_block_type); | |
} | |
template<class T> | |
void load_grid_loc(const pugi::xml_node &root, T &out, void *data){ | |
if(root.first_child().type() == pugi::node_element) | |
throw std::runtime_error("Unexpected child element in <grid_loc>."); | |
std::bitset<5> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_grid_loc in = lex_attr_t_grid_loc(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <grid_loc>."); | |
switch(in){ | |
case atok_t_grid_loc::BLOCK_TYPE_ID: | |
out.set_grid_loc_block_type_id(load_int(attr.value()), data); | |
break; | |
case atok_t_grid_loc::HEIGHT_OFFSET: | |
out.set_grid_loc_height_offset(load_int(attr.value()), data); | |
break; | |
case atok_t_grid_loc::WIDTH_OFFSET: | |
out.set_grid_loc_width_offset(load_int(attr.value()), data); | |
break; | |
case atok_t_grid_loc::X: | |
out.set_grid_loc_x(load_int(attr.value()), data); | |
break; | |
case atok_t_grid_loc::Y: | |
out.set_grid_loc_y(load_int(attr.value()), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<5> test_astate = astate | std::bitset<5>(0b00000); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_grid_loc); | |
} | |
template<class T> | |
void load_node_loc(const pugi::xml_node &root, T &out, void *data){ | |
if(root.first_child().type() == pugi::node_element) | |
throw std::runtime_error("Unexpected child element in <node_loc>."); | |
std::bitset<6> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_node_loc in = lex_attr_t_node_loc(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <node_loc>."); | |
switch(in){ | |
case atok_t_node_loc::PTC: | |
out.set_node_loc_ptc(load_int(attr.value()), data); | |
break; | |
case atok_t_node_loc::SIDE: | |
out.set_node_loc_side(lex_enum_loc_side(attr.value(), true), data); | |
break; | |
case atok_t_node_loc::XHIGH: | |
out.set_node_loc_xhigh(load_int(attr.value()), data); | |
break; | |
case atok_t_node_loc::XLOW: | |
out.set_node_loc_xlow(load_int(attr.value()), data); | |
break; | |
case atok_t_node_loc::YHIGH: | |
out.set_node_loc_yhigh(load_int(attr.value()), data); | |
break; | |
case atok_t_node_loc::YLOW: | |
out.set_node_loc_ylow(load_int(attr.value()), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<6> test_astate = astate | std::bitset<6>(0b000010); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_node_loc); | |
} | |
template<class T> | |
void load_node_timing(const pugi::xml_node &root, T &out, void *data){ | |
if(root.first_child().type() == pugi::node_element) | |
throw std::runtime_error("Unexpected child element in <node_timing>."); | |
std::bitset<2> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_node_timing in = lex_attr_t_node_timing(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <node_timing>."); | |
switch(in){ | |
case atok_t_node_timing::C: | |
out.set_node_timing_C(load_float(attr.value()), data); | |
break; | |
case atok_t_node_timing::R: | |
out.set_node_timing_R(load_float(attr.value()), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<2> test_astate = astate | std::bitset<2>(0b00); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_node_timing); | |
} | |
template<class T> | |
void load_node_segment(const pugi::xml_node &root, T &out, void *data){ | |
if(root.first_child().type() == pugi::node_element) | |
throw std::runtime_error("Unexpected child element in <node_segment>."); | |
std::bitset<1> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_node_segment in = lex_attr_t_node_segment(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <node_segment>."); | |
switch(in){ | |
case atok_t_node_segment::SEGMENT_ID: | |
out.set_node_segment_segment_id(load_int(attr.value()), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<1> test_astate = astate | std::bitset<1>(0b0); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_node_segment); | |
} | |
template<class T> | |
void load_node_connection_box(const pugi::xml_node &root, T &out, void *data){ | |
if(root.first_child().type() == pugi::node_element) | |
throw std::runtime_error("Unexpected child element in <node_connection_box>."); | |
std::bitset<3> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_node_connection_box in = lex_attr_t_node_connection_box(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <node_connection_box>."); | |
switch(in){ | |
case atok_t_node_connection_box::ID: | |
out.set_node_connection_box_id(load_int(attr.value()), data); | |
break; | |
case atok_t_node_connection_box::X: | |
out.set_node_connection_box_x(load_int(attr.value()), data); | |
break; | |
case atok_t_node_connection_box::Y: | |
out.set_node_connection_box_y(load_int(attr.value()), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<3> test_astate = astate | std::bitset<3>(0b000); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_node_connection_box); | |
} | |
template<class T> | |
void load_node_canonical_loc(const pugi::xml_node &root, T &out, void *data){ | |
if(root.first_child().type() == pugi::node_element) | |
throw std::runtime_error("Unexpected child element in <node_canonical_loc>."); | |
std::bitset<2> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_node_canonical_loc in = lex_attr_t_node_canonical_loc(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <node_canonical_loc>."); | |
switch(in){ | |
case atok_t_node_canonical_loc::X: | |
out.set_node_canonical_loc_x(load_int(attr.value()), data); | |
break; | |
case atok_t_node_canonical_loc::Y: | |
out.set_node_canonical_loc_y(load_int(attr.value()), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<2> test_astate = astate | std::bitset<2>(0b00); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_node_canonical_loc); | |
} | |
template<class T> | |
void load_node(const pugi::xml_node &root, T &out, void *data){ | |
std::bitset<6> gstate = 0; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_node in = lex_node_t_node(node.name()); | |
if(gstate[(int)in] == 0) gstate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate element " + std::string(node.name()) + " in <node>."); | |
switch(in){ | |
case gtok_t_node::LOC: | |
load_node_loc(node, out.init_node_loc(data)); | |
break; | |
case gtok_t_node::TIMING: | |
load_node_timing(node, out.init_node_timing(data)); | |
break; | |
case gtok_t_node::SEGMENT: | |
load_node_segment(node, out.init_node_segment(data)); | |
break; | |
case gtok_t_node::CONNECTION_BOX: | |
load_node_connection_box(node, out.init_node_connection_box(data)); | |
break; | |
case gtok_t_node::CANONICAL_LOC: | |
load_node_canonical_loc(node, out.init_node_canonical_loc(data)); | |
break; | |
case gtok_t_node::METADATA: | |
load_metadata(node, out.init_node_metadata(data)); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<6> test_gstate = gstate | std::bitset<6>(0b111110); | |
if(!test_gstate.all()) all_error(test_gstate, gtok_lookup_t_node); | |
std::bitset<4> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_node in = lex_attr_t_node(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <node>."); | |
switch(in){ | |
case atok_t_node::CAPACITY: | |
out.set_node_capacity(load_unsigned_int(attr.value()), data); | |
break; | |
case atok_t_node::DIRECTION: | |
out.set_node_direction(lex_enum_node_direction(attr.value(), true), data); | |
break; | |
case atok_t_node::ID: | |
out.set_node_id(load_unsigned_int(attr.value()), data); | |
break; | |
case atok_t_node::TYPE: | |
out.set_node_type(lex_enum_node_type(attr.value(), true), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<4> test_astate = astate | std::bitset<4>(0b0010); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_node); | |
} | |
template<class T> | |
void load_edge(const pugi::xml_node &root, T &out, void *data){ | |
std::bitset<1> gstate = 0; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_edge in = lex_node_t_edge(node.name()); | |
if(gstate[(int)in] == 0) gstate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate element " + std::string(node.name()) + " in <edge>."); | |
switch(in){ | |
case gtok_t_edge::METADATA: | |
load_metadata(node, out.init_edge_metadata(data)); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<1> test_gstate = gstate | std::bitset<1>(0b1); | |
if(!test_gstate.all()) all_error(test_gstate, gtok_lookup_t_edge); | |
std::bitset<4> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_edge in = lex_attr_t_edge(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <edge>."); | |
switch(in){ | |
case atok_t_edge::ID: | |
out.set_edge_id(load_unsigned_int(attr.value()), data); | |
break; | |
case atok_t_edge::SINK_NODE: | |
out.set_edge_sink_node(load_unsigned_int(attr.value()), data); | |
break; | |
case atok_t_edge::SRC_NODE: | |
out.set_edge_src_node(load_unsigned_int(attr.value()), data); | |
break; | |
case atok_t_edge::SWITCH_ID: | |
out.set_edge_switch_id(load_unsigned_int(attr.value()), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<4> test_astate = astate | std::bitset<4>(0b0001); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_edge); | |
} | |
static const int NUM_T_CHANNELS_STATES = 4; | |
static const int NUM_T_CHANNELS_INPUTS = 3; | |
static int gstate_t_channels[NUM_T_CHANNELS_STATES][NUM_T_CHANNELS_INPUTS] = { | |
{-1, -1, 0}, | |
{-1, 1, 0}, | |
{-1, 1, -1}, | |
{2, -1, -1}, | |
}; | |
template<class T> | |
void load_channels(const pugi::xml_node &root, T &out, void *data){ | |
int next, state=3; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_channels in = lex_node_t_channels(node.name()); | |
next = gstate_t_channels[state][(int)in]; | |
if(next == -1) | |
dfa_error(gtok_lookup_t_channels[(int)in], gstate_t_channels[state], gtok_lookup_t_channels, 3); | |
state = next; | |
switch(in){ | |
case gtok_t_channels::CHANNEL: | |
load_channel(node, out.init_channels_channel(data)); | |
break; | |
case gtok_t_channels::X_LIST: | |
load_x_list(node, out.add_channels_x_list(data)); | |
break; | |
case gtok_t_channels::Y_LIST: | |
load_y_list(node, out.add_channels_y_list(data)); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_channels[state], gtok_lookup_t_channels, 3); | |
if(root.first_attribute()) | |
throw std::runtime_error("Unexpected attribute in <channels>."); | |
} | |
static const int NUM_T_SWITCHES_STATES = 2; | |
static const int NUM_T_SWITCHES_INPUTS = 1; | |
static int gstate_t_switches[NUM_T_SWITCHES_STATES][NUM_T_SWITCHES_INPUTS] = { | |
{0}, | |
{0}, | |
}; | |
template<class T> | |
void load_switches(const pugi::xml_node &root, T &out, void *data){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_switches in = lex_node_t_switches(node.name()); | |
next = gstate_t_switches[state][(int)in]; | |
if(next == -1) | |
dfa_error(gtok_lookup_t_switches[(int)in], gstate_t_switches[state], gtok_lookup_t_switches, 1); | |
state = next; | |
switch(in){ | |
case gtok_t_switches::SWITCH: | |
load_switch(node, out.add_switches_switch(data)); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_switches[state], gtok_lookup_t_switches, 1); | |
if(root.first_attribute()) | |
throw std::runtime_error("Unexpected attribute in <switches>."); | |
} | |
static const int NUM_T_SEGMENTS_STATES = 2; | |
static const int NUM_T_SEGMENTS_INPUTS = 1; | |
static int gstate_t_segments[NUM_T_SEGMENTS_STATES][NUM_T_SEGMENTS_INPUTS] = { | |
{0}, | |
{0}, | |
}; | |
template<class T> | |
void load_segments(const pugi::xml_node &root, T &out, void *data){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_segments in = lex_node_t_segments(node.name()); | |
next = gstate_t_segments[state][(int)in]; | |
if(next == -1) | |
dfa_error(gtok_lookup_t_segments[(int)in], gstate_t_segments[state], gtok_lookup_t_segments, 1); | |
state = next; | |
switch(in){ | |
case gtok_t_segments::SEGMENT: | |
load_segment(node, out.add_segments_segment(data)); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_segments[state], gtok_lookup_t_segments, 1); | |
if(root.first_attribute()) | |
throw std::runtime_error("Unexpected attribute in <segments>."); | |
} | |
static const int NUM_T_BLOCK_TYPES_STATES = 2; | |
static const int NUM_T_BLOCK_TYPES_INPUTS = 1; | |
static int gstate_t_block_types[NUM_T_BLOCK_TYPES_STATES][NUM_T_BLOCK_TYPES_INPUTS] = { | |
{0}, | |
{0}, | |
}; | |
template<class T> | |
void load_block_types(const pugi::xml_node &root, T &out, void *data){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_block_types in = lex_node_t_block_types(node.name()); | |
next = gstate_t_block_types[state][(int)in]; | |
if(next == -1) | |
dfa_error(gtok_lookup_t_block_types[(int)in], gstate_t_block_types[state], gtok_lookup_t_block_types, 1); | |
state = next; | |
switch(in){ | |
case gtok_t_block_types::BLOCK_TYPE: | |
load_block_type(node, out.add_block_types_block_type(data)); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_block_types[state], gtok_lookup_t_block_types, 1); | |
if(root.first_attribute()) | |
throw std::runtime_error("Unexpected attribute in <block_types>."); | |
} | |
static const int NUM_T_GRID_LOCS_STATES = 2; | |
static const int NUM_T_GRID_LOCS_INPUTS = 1; | |
static int gstate_t_grid_locs[NUM_T_GRID_LOCS_STATES][NUM_T_GRID_LOCS_INPUTS] = { | |
{0}, | |
{0}, | |
}; | |
template<class T> | |
void load_grid_locs(const pugi::xml_node &root, T &out, void *data){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_grid_locs in = lex_node_t_grid_locs(node.name()); | |
next = gstate_t_grid_locs[state][(int)in]; | |
if(next == -1) | |
dfa_error(gtok_lookup_t_grid_locs[(int)in], gstate_t_grid_locs[state], gtok_lookup_t_grid_locs, 1); | |
state = next; | |
switch(in){ | |
case gtok_t_grid_locs::GRID_LOC: | |
load_grid_loc(node, out.add_grid_locs_grid_loc(data)); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_grid_locs[state], gtok_lookup_t_grid_locs, 1); | |
if(root.first_attribute()) | |
throw std::runtime_error("Unexpected attribute in <grid_locs>."); | |
} | |
static const int NUM_T_RR_NODES_STATES = 2; | |
static const int NUM_T_RR_NODES_INPUTS = 1; | |
static int gstate_t_rr_nodes[NUM_T_RR_NODES_STATES][NUM_T_RR_NODES_INPUTS] = { | |
{0}, | |
{0}, | |
}; | |
template<class T> | |
void load_rr_nodes(const pugi::xml_node &root, T &out, void *data){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_rr_nodes in = lex_node_t_rr_nodes(node.name()); | |
next = gstate_t_rr_nodes[state][(int)in]; | |
if(next == -1) | |
dfa_error(gtok_lookup_t_rr_nodes[(int)in], gstate_t_rr_nodes[state], gtok_lookup_t_rr_nodes, 1); | |
state = next; | |
switch(in){ | |
case gtok_t_rr_nodes::NODE: | |
load_node(node, out.add_rr_nodes_node(data)); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_rr_nodes[state], gtok_lookup_t_rr_nodes, 1); | |
if(root.first_attribute()) | |
throw std::runtime_error("Unexpected attribute in <rr_nodes>."); | |
} | |
static const int NUM_T_RR_EDGES_STATES = 2; | |
static const int NUM_T_RR_EDGES_INPUTS = 1; | |
static int gstate_t_rr_edges[NUM_T_RR_EDGES_STATES][NUM_T_RR_EDGES_INPUTS] = { | |
{0}, | |
{0}, | |
}; | |
template<class T> | |
void load_rr_edges(const pugi::xml_node &root, T &out, void *data){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_rr_edges in = lex_node_t_rr_edges(node.name()); | |
next = gstate_t_rr_edges[state][(int)in]; | |
if(next == -1) | |
dfa_error(gtok_lookup_t_rr_edges[(int)in], gstate_t_rr_edges[state], gtok_lookup_t_rr_edges, 1); | |
state = next; | |
switch(in){ | |
case gtok_t_rr_edges::EDGE: | |
load_edge(node, out.add_rr_edges_edge(data)); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_rr_edges[state], gtok_lookup_t_rr_edges, 1); | |
if(root.first_attribute()) | |
throw std::runtime_error("Unexpected attribute in <rr_edges>."); | |
} | |
template<class T> | |
void load_bin_nodes(const pugi::xml_node &root, T &out, void *data){ | |
if(root.first_child().type() == pugi::node_element) | |
throw std::runtime_error("Unexpected child element in <bin_nodes>."); | |
std::bitset<1> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_bin_nodes in = lex_attr_t_bin_nodes(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <bin_nodes>."); | |
switch(in){ | |
case atok_t_bin_nodes::FILE: | |
out.set_bin_nodes_file(attr.value(), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<1> test_astate = astate | std::bitset<1>(0b1); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_bin_nodes); | |
} | |
template<class T> | |
void load_connection_box(const pugi::xml_node &root, T &out, void *data){ | |
if(root.first_child().type() == pugi::node_element) | |
throw std::runtime_error("Unexpected child element in <connection_box>."); | |
std::bitset<2> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_connection_box in = lex_attr_t_connection_box(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <connection_box>."); | |
switch(in){ | |
case atok_t_connection_box::ID: | |
out.set_connection_box_id(load_unsigned_int(attr.value()), data); | |
break; | |
case atok_t_connection_box::NAME: | |
out.set_connection_box_name(attr.value(), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<2> test_astate = astate | std::bitset<2>(0b00); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_connection_box); | |
} | |
static const int NUM_T_CONNECTION_BOXES_STATES = 2; | |
static const int NUM_T_CONNECTION_BOXES_INPUTS = 1; | |
static int gstate_t_connection_boxes[NUM_T_CONNECTION_BOXES_STATES][NUM_T_CONNECTION_BOXES_INPUTS] = { | |
{0}, | |
{0}, | |
}; | |
template<class T> | |
void load_connection_boxes(const pugi::xml_node &root, T &out, void *data){ | |
int next, state=1; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_connection_boxes in = lex_node_t_connection_boxes(node.name()); | |
next = gstate_t_connection_boxes[state][(int)in]; | |
if(next == -1) | |
dfa_error(gtok_lookup_t_connection_boxes[(int)in], gstate_t_connection_boxes[state], gtok_lookup_t_connection_boxes, 1); | |
state = next; | |
switch(in){ | |
case gtok_t_connection_boxes::CONNECTION_BOX: | |
load_connection_box(node, out.add_connection_boxes_connection_box(data)); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
if(state != 0) dfa_error("end of input", gstate_t_connection_boxes[state], gtok_lookup_t_connection_boxes, 1); | |
std::bitset<3> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_connection_boxes in = lex_attr_t_connection_boxes(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <connection_boxes>."); | |
switch(in){ | |
case atok_t_connection_boxes::NUM_BOXES: | |
out.set_connection_boxes_num_boxes(load_unsigned_int(attr.value()), data); | |
break; | |
case atok_t_connection_boxes::X_DIM: | |
out.set_connection_boxes_x_dim(load_int(attr.value()), data); | |
break; | |
case atok_t_connection_boxes::Y_DIM: | |
out.set_connection_boxes_y_dim(load_int(attr.value()), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<3> test_astate = astate | std::bitset<3>(0b000); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_connection_boxes); | |
} | |
template<class T> | |
void load_rr_graph(const pugi::xml_node &root, T &out, void *data){ | |
std::bitset<9> gstate = 0; | |
for(pugi::xml_node node = root.first_child(); node; node = node.next_sibling()){ | |
gtok_t_rr_graph in = lex_node_t_rr_graph(node.name()); | |
if(gstate[(int)in] == 0) gstate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate element " + std::string(node.name()) + " in <rr_graph>."); | |
switch(in){ | |
case gtok_t_rr_graph::BINARY_NODES_AND_EDGES: | |
load_bin_nodes(node, out.init_rr_graph_binary_nodes_and_edges(data)); | |
break; | |
case gtok_t_rr_graph::CONNECTION_BOXES: | |
load_connection_boxes(node, out.init_rr_graph_connection_boxes(data)); | |
break; | |
case gtok_t_rr_graph::CHANNELS: | |
load_channels(node, out.init_rr_graph_channels(data)); | |
break; | |
case gtok_t_rr_graph::SWITCHES: | |
load_switches(node, out.init_rr_graph_switches(data)); | |
break; | |
case gtok_t_rr_graph::SEGMENTS: | |
load_segments(node, out.init_rr_graph_segments(data)); | |
break; | |
case gtok_t_rr_graph::BLOCK_TYPES: | |
load_block_types(node, out.init_rr_graph_block_types(data)); | |
break; | |
case gtok_t_rr_graph::GRID: | |
load_grid_locs(node, out.init_rr_graph_grid(data)); | |
break; | |
case gtok_t_rr_graph::RR_NODES: | |
load_rr_nodes(node, out.init_rr_graph_rr_nodes(data)); | |
break; | |
case gtok_t_rr_graph::RR_EDGES: | |
load_rr_edges(node, out.init_rr_graph_rr_edges(data)); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<9> test_gstate = gstate | std::bitset<9>(0b000000011); | |
if(!test_gstate.all()) all_error(test_gstate, gtok_lookup_t_rr_graph); | |
std::bitset<3> astate = 0; | |
for(pugi::xml_attribute attr = root.first_attribute(); attr; attr = attr.next_attribute()){ | |
atok_t_rr_graph in = lex_attr_t_rr_graph(attr.name()); | |
if(astate[(int)in] == 0) astate[(int)in] = 1; | |
else throw std::runtime_error("Duplicate attribute " + std::string(attr.name()) + " in <rr_graph>."); | |
switch(in){ | |
case atok_t_rr_graph::TOOL_COMMENT: | |
out.set_rr_graph_tool_comment(attr.value(), data); | |
break; | |
case atok_t_rr_graph::TOOL_NAME: | |
out.set_rr_graph_tool_name(attr.value(), data); | |
break; | |
case atok_t_rr_graph::TOOL_VERSION: | |
out.set_rr_graph_tool_version(attr.value(), data); | |
break; | |
default: break; /* Not possible. */ | |
} | |
} | |
std::bitset<3> test_astate = astate | std::bitset<3>(0b111); | |
if(!test_astate.all()) attr_error(test_astate, atok_lookup_t_rr_graph); | |
} | |
inline void dfa_error(const char *wrong, int *states, const char **lookup, int len){ | |
std::vector<std::string> expected; | |
for(int i=0; i<len; i++){ | |
if(states[i] != -1) expected.push_back(lookup[i]); | |
} | |
std::string expected_or = expected[0]; | |
for(unsigned int i=1; i<expected.size(); i++) | |
expected_or += std::string(" or ") + expected[i]; | |
throw std::runtime_error("Expected " + expected_or + ", found " + std::string(wrong)); | |
} | |
template<std::size_t N> | |
inline void all_error(std::bitset<N> gstate, const char **lookup){ | |
std::vector<std::string> missing; | |
for(unsigned int i=0; i<N; i++){ | |
if(gstate[i] == 0) missing.push_back(lookup[i]); | |
} | |
std::string missing_and = missing[0]; | |
for(unsigned int i=1; i<missing.size(); i++) | |
missing_and += std::string(", ") + missing[i]; | |
throw std::runtime_error("Didn't find required elements " + missing_and + "."); | |
} | |
template<std::size_t N> | |
inline void attr_error(std::bitset<N> astate, const char **lookup){ | |
std::vector<std::string> missing; | |
for(unsigned int i=0; i<N; i++){ | |
if(astate[i] == 0) missing.push_back(lookup[i]); | |
} | |
std::string missing_and = missing[0]; | |
for(unsigned int i=1; i<missing.size(); i++) | |
missing_and += std::string(", ") + missing[i]; | |
throw std::runtime_error("Didn't find required attributes " + missing_and + "."); | |
} | |
} /* namespace uxsd */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment