/** * compilerkit_alpha_numeric_character_class_new: * @fn compilerkit_alpha_numeric_character_class_new * * Constructs an alphanumeric character class object (internally the equivalent CompilerKitAlternation). * * For example, `compilerkit_character_class_new('0','z')` produces the regex `[0-9A-Za-z]`. * Note that only alphanumeric characters will be included in the character class, and nothing else. * * @pre None. * @param gunichar `lo` The low end of the character class. If this is `'\0'`, `lo` is the next higher character. * @param gunichar `hi` The high end of the character class. If this is `'\0'`, return the empty string. * @return GObject* a pointer to the new character class regex, or NULL if `lo` or `hi` are non-alphanumeric. */ GObject* compilerkit_alpha_numeric_character_class_new(gunichar lo, gunichar hi) { GObject *result; if (!compilerkit_character_is_alpha_numeric(lo)) return NULL; if (!compilerkit_character_is_alpha_numeric(hi)) return NULL; sort_chars (&lo, &hi); result = compilerkit_empty_set_get_instance (); if (lo <= '9' && hi >= 'A') { result = compilerkit_character_class_new (lo, '9'); lo = 'A'; } if ('A' <= lo && lo <= 'Z' && hi >= 'a') { result = compilerkit_alternation_new (result, compilerkit_character_class_new (lo, 'Z')); lo = 'a'; } if ('a' <= lo) { result = compilerkit_alternation_new (result, compilerkit_character_class_new (lo, hi)); } return result; }
int main (int argc, char ** argv) { GObject *alternationOne; GObject *alternationTwo; GObject *left; GObject *right; GObject *left_left; GObject *left_right; GObject *subAlternation; g_type_init(); alternationOne = compilerkit_alternation_new(compilerkit_symbol_new('a'),compilerkit_symbol_new('b')); // creates an alternation ('a' | 'b') alternationTwo = compilerkit_alternation_vlist_new(compilerkit_symbol_new('c'), compilerkit_symbol_new('d'), compilerkit_symbol_new('e'), NULL); //NULL terminated list of at least 2 GObjects //creates an alternation (('c' | 'd') | 'e') left = compilerkit_alternation_get_left(alternationOne); //returns the symbol 'a' right = compilerkit_alternation_get_right(alternationOne); //returns the symbol 'b' subAlternation = compilerkit_alternation_get_left(alternationTwo); //returns the alternation ('c' | 'd') left_left = compilerkit_alternation_get_left(compilerkit_alternation_get_left(alternationTwo)); //returns the symbol 'c' left_right = compilerkit_alternation_get_right(compilerkit_alternation_get_left(alternationTwo)); //returns the symbol 'd' right = compilerkit_alternation_get_right(alternationTwo); //returns the symbol 'e' g_object_unref (alternationOne); //Also de-references the parts (left and right) g_object_unref (alternationTwo); //Also de-references the parts (subAlternation, left_left, left_right, and right) }
/** * compilerkit_character_class_new: * @fn compilerkit_character_class_new * * Constructs a character class object (internally the equivalent CompilerKitAlternation). * * For example, `compilerkit_character_class_new('a','z')` produces the regex `[a-z]`. * `compilerkit_character_class_new('!','~')` produces the a regex to match all characters between ASCII '!' and '~' (this happens to include all Latin printable characters). * * @pre None. * @param gunichar `lo` The low end of the character class. If this is `'\0'`, `lo` is the next higher character. * @param gunichar `hi` The high end of the character class. If this is `'\0'`, return the empty string. * @return GObject* a pointer to the new character class regex. */ GObject* compilerkit_character_class_new(gunichar lo, gunichar hi) { GObject* newExpression; gunichar i; sort_chars (&lo, &hi); /* If they're the same, return the symbol instead. */ if (lo == hi) { return compilerkit_symbol_new (lo); } /* Don't match NULL in the regex */ if (lo == '\0') { lo++; } /* This must mean lo and hi are both NULL. Return EmptyString instead. */ else if (hi == '\0') { return compilerkit_empty_string_get_instance(); } newExpression = compilerkit_symbol_new(lo); for(i = lo+1; i <= hi; i++) { newExpression = compilerkit_alternation_new (newExpression, compilerkit_symbol_new(i)); } return newExpression; }
/** * compilerkit_alternation_vlist_new: * @fn compilerkit_alternation_vlist_new * @memberof CompilerKitAlternation * Construct a CompilerKitAlternation instance. * @pre all GObject* until the last one are all non NULL, and the last arg must be NULL. * @param GObject* left the first parameter in an alternation * @param GObject* right the second parameter in an alternation * @param ... Comma separated list of GObject*, terminated by a NULL param * @return A new GObject struct. */ GObject* compilerkit_alternation_vlist_new (GObject *left, GObject *right, ...) { GObject* first; GObject* second; va_list args; va_start(args,right); first = compilerkit_alternation_new(left, right); while(1) { second = va_arg(args, GObject*); if(second == NULL) { break; } first = compilerkit_alternation_new(first, second); } va_end(args); return G_OBJECT(first); }
/** * test_alternation_constructor: * @fn test_alternation_constructor * Tests method compilerkit_alternation_new in CompilerKitAlternation struct. * @pre None * @param None * @return void */ void test_alternation_constructor (void) { GObject* alt; GObject* left; GObject* right; g_test_message ("Testing Alternation constructor"); g_test_timer_start (); left = compilerkit_symbol_new('a'); right = compilerkit_symbol_new('b'); alt = compilerkit_alternation_new(left, right); g_assert (COMPILERKIT_IS_ALTERNATION(alt)); g_assert (left != right); g_assert (left != alt); g_assert (right != alt); g_object_unref (alt); // This will unref left and right as well g_assert_cmpfloat(g_test_timer_elapsed (), <=, 1); }
/** * compilerkit_optional_new: * @fn compilerkit_optional_new * * Return a regex corresponding to the original regex|empty string * * @pre regex is not NULL * @param GObject* regex to make optional * @return GObject* Alternation of the regex with the empty string */ GObject *compilerkit_optional_new (GObject *regex) { return compilerkit_alternation_new (regex, compilerkit_empty_string_get_instance()); }