13 namespace xilinx_toolbox
19 TokenStream<std::string> tokenize(std::stringstream& ss)
21 const std::string delimiters =
" ";
22 std::string current_token;
28 std::vector<Token<std::string>> parsed_tokens;
29 while (std::getline(ss, line))
41 else if (escaped && std::isspace(c))
47 if (((!std::isspace(c) && delimiters.find(c) == std::string::npos) || escaped))
53 if (!current_token.empty())
55 parsed_tokens.emplace_back(line_number, current_token);
56 current_token.clear();
61 parsed_tokens.emplace_back(line_number, std::string(1, c));
66 if (!current_token.empty())
68 parsed_tokens.emplace_back(line_number, current_token);
69 current_token.clear();
73 return TokenStream(parsed_tokens, {}, {});
76 Result<LOC> parse_LOC(TokenStream<std::string>& ts)
78 const auto loc_token = ts.consume();
79 std::string loc_str = loc_token.string;
82 new_loc.loc_name = loc_str;
85 const auto pin_pattern = std::regex(
"^[a-zA-Z]\\d+$");
87 if (std::regex_match(loc_str, match, pin_pattern))
93 const std::string loc_type_str = loc_str.substr(0, loc_str.find_first_of(
"_"));
95 if (is_valid_enum<LOCType>(loc_type_str))
97 new_loc.loc_type = enum_from_string<LOCType>(loc_type_str);
101 return ERR(
"cannot parse LOC: encountered unknown LOC type '" + loc_type_str +
"'" +
" at line " + std::to_string(loc_token.number));
104 loc_str = loc_str.substr(loc_type_str.size());
105 loc_str = loc_str.substr(std::string(
"_X").
size());
107 const std::string x_str = loc_str.substr(0, loc_str.find_first_of(
"Y"));
109 loc_str = loc_str.substr(x_str.size());
110 loc_str = loc_str.substr(std::string(
"Y").
size());
112 const std::string y_str = loc_str;
116 new_loc.loc_x = res.get();
120 return ERR_APPEND(res.get_error(),
"cannot parse LOC: failed to extract x position form " + loc_token.string +
" at line " + std::to_string(loc_token.number));
125 new_loc.loc_y = res.get();
129 return ERR_APPEND(res.get_error(),
"cannot parse LOC: failed to extract y position form " + loc_token.string +
" at line " + std::to_string(loc_token.number));
135 Result<std::string> parse_single_cell(TokenStream<std::string>& ts)
137 const auto loc_token = ts.consume();
138 if (loc_token.string !=
"[get_cells")
140 return ERR(
"cannot parse cell name: expected token " + loc_token.string +
" at line " + std::to_string(loc_token.number) +
" to be exactly '[get_cells'");
143 const auto cell_token = ts.consume();
144 std::string cell_str = cell_token.string;
146 bool is_escpaed = cell_str.substr(0, 1) ==
"{" && cell_str.substr(cell_str.size() - 2, 1) ==
"}";
148 if (cell_str.substr(cell_str.size() - 1, 1) !=
"]")
150 return ERR(
"cannot parse cell name: expected cell token '" + cell_str +
" at line " + std::to_string(loc_token.number) +
"' to end with ']'");
153 cell_str = cell_str.substr(is_escpaed ? 1 : 0, cell_str.size() - (is_escpaed ? 2 : 1));
158 Result<std::unordered_map<std::string, CellData>> parse_tokens(TokenStream<std::string>& ts)
160 std::unordered_map<std::string, CellData> cell_data;
164 ts.consume_until(
"set_property");
165 if (ts.remaining() == 0)
170 ts.consume(
"set_property");
172 if (ts.peek().string ==
"BEL")
176 const auto bel_type = enum_from_string<BELType>(ts.consume().string);
178 if (
const auto res = parse_single_cell(ts); res.is_ok())
180 cell_data[res.get()].bel_type = bel_type;
184 return ERR_APPEND(res.get_error(),
"cannot parse xdc token stream: failed to extract cell name");
187 else if (ts.peek().string ==
"LOC")
192 if (
const auto res = parse_LOC(ts); res.is_ok())
198 return ERR_APPEND(res.get_error(),
"cannot parse xdc token stream: failed to extract LOC");
201 if (
const auto res = parse_single_cell(ts); res.is_ok())
203 cell_data[res.get()].loc = new_loc;
207 return ERR_APPEND(res.get_error(),
"cannot parse xdc token stream: failed to extract cell name");
212 ts.consume_current_line();
216 return OK(cell_data);
222 return ERR(
"not implemented");
#define ERR_APPEND(prev_error, message)
Result< u64 > wrapped_stoull(const std::string &s, const u32 base=10)