TokenType token_type(const string &str) { if (is_valid_operator(str)) return operator_symbol; if (is_valid_operator_as_function(str)) return op_function; if (is_valid_identifier(str)) return plain_identifier; if (is_valid_symbol(str)) return symbol; if (is_valid_label(str)) return label; if (is_valid_number(str)) return number; if (is_valid_type_name(str)) return type_id; if (is_valid_type_var(str)) return type_var; if (is_valid_builtin(str)) return builtin; if (is_valid_string_lit(str)) return string_lit; return invalid; }
unsigned SudokuFormat::count_cells(const std::string& str) { unsigned count = 0; for (char c : str) { if (is_valid_label(c) || is_empty(c)) { ++count; } } return count; }
std::string SudokuFormat::choose_labels(const std::string& str, unsigned n) { auto used = std::set<char>(); for (char c : str) { if (is_valid_label(c)) { used.insert(c); } } if (used.size() > n) { throw std::invalid_argument("Too many different labels"); } auto has_digit = false; auto has_upper = false; auto has_lower = false; for (char c : used) { if (::isdigit(c)) { has_digit = true; } else if (::isupper(c)) { has_upper = true; } else if (::islower(c)) { has_lower = true; } } for (char c : valid_labels()) { if (used.size() >= n) { continue; } if ((::isdigit(c) && has_digit) || (::islower(c) && has_lower) || (::isupper(c) && has_upper)) { used.insert(c); } } for (char c : valid_labels()) { if (used.size() < n) { used.insert(c); } } if (used.size() < n) { throw std::invalid_argument("Sudoku too large, not enough labels"); } std::string labels; for (char c : used) { labels += c; } return labels; }
/* Reads STR and determines whether it is a label (ends in ':'), and if so, whether it is a valid label, and then tries to add it to the symbol table. INPUT_LINE is which line of the input file we are currently processing. Note that the first line is line 1 and that empty lines are included in this count. BYTE_OFFSET is the offset of the NEXT instruction (should it exist). Four scenarios can happen: 1. STR is not a label (does not end in ':'). Returns 0. 2. STR ends in ':', but is not a valid label. Returns -1. 3a. STR ends in ':' and is a valid label. Addition to symbol table fails. Returns -1. 3b. STR ends in ':' and is a valid label. Addition to symbol table succeeds. Returns 1. */ static int add_if_label(uint32_t input_line, char* str, uint32_t byte_offset, SymbolTable* symtbl) { size_t len = strlen(str); if (str[len - 1] == ':') { str[len - 1] = '\0'; if (is_valid_label(str)) { if (add_to_table(symtbl, str, byte_offset) == 0) { return 1; } else { return -1; } } else { raise_label_error(input_line, str); return -1; } } else { return 0; } }
bool SudokuFormat::is_valid_cell(char c) { return is_valid_label(c) || is_empty(c); }