Skip to content

Instantly share code, notes, and snippets.

@xfbs
Last active November 11, 2018 21:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xfbs/66ee09fd0fe6249f9a83ca950a0cc614 to your computer and use it in GitHub Desktop.
Save xfbs/66ee09fd0fe6249f9a83ca950a0cc614 to your computer and use it in GitHub Desktop.
Program to count identifiers.
CFLAGS += $(shell pkg-config --cflags glib-2.0)
LDFLAGS += $(shell pkg-config --libs glib-2.0)
all: task
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <glib.h>
#include <assert.h>
// read a single line from input.
GString *get_line() {
// read line
char *line = NULL;
size_t line_length;
getline(&line, &line_length, stdin);
// truncate newline
g_strstrip(line);
return g_string_new(line);
}
// check if the next word on the input is a valid identifier.
bool is_identifier(const char *word) {
// compile the regular expression
const GRegex *regex = g_regex_new("^[a-zA-Z_][a-zA-Z0-9_]*$", G_REGEX_OPTIMIZE, 0, NULL);
return g_regex_match(regex, word, 0, NULL);
}
// counts the unique identifiers in a list of words.
int count_identifiers(gchar **words) {
// find identifiers. by using a hash table, we know that repeated identifiers
// are only counted once.
GHashTable *identifiers = g_hash_table_new(g_str_hash, g_str_equal);
for(size_t pos = 0; words[pos]; ++pos) {
if(is_identifier(words[pos])) {
g_hash_table_insert(identifiers, words[pos], NULL);
printf("identifier: '%s'\n", words[pos]);
}
}
// find out how many unique identifiers there are
int count = g_hash_table_size(identifiers);
g_hash_table_destroy(identifiers);
return count;
}
// read a single line from the input, parse it, and return the number of
// identifiers found on it.
int parse_line() {
// read a single line from input and split into words.
GString *line = get_line();
gchar **words = g_strsplit(line->str, " ", 0);
int count = count_identifiers(words);
free(g_string_free(line, false));
g_strfreev(words);
return count;
}
// tests to make sure everything works as intended
void test() {
assert(is_identifier("Identifier9_"));
assert(is_identifier("ALLCAPS"));
assert(is_identifier("allsmall"));
assert(is_identifier("________"));
assert(is_identifier("i1431"));
assert(!is_identifier("------"));
assert(!is_identifier("9gag"));
// you can add more tests here to make sure the functions work.
}
int main(int argc, char *argv[]) {
test();
// parse data until it's empty.
while(!feof(stdin)) {
printf("found %i identifiers.\n", parse_line());
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment