Commit db2dbc28 by Aaron Leung

Need to change the API slightly to return char *s instead of ints.

parent cd5a1d00
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include "prefix_primitives.h"
char *prefix_is_char(char *src, char pre) {
return pre == *src ? src+1 : NULL;
}
char *prefix_is_chars(char *src, char *pre) {
while (*pre && *src == *pre) src++, pre++;
return *pre ? NULL : src;
}
char *prefix_is_one_of(char *src, char *class) {
while(*class && *src != *class) class++;
return *class ? src+1 : NULL;
}
char *prefix_is_some_of(char *src, char *class) {
char *p = src;
while(prefix_is_one_of(p, class)) p++;
return p == src ? NULL : p;
}
char *prefix_is_delimited_by(char *src, char *beg, char *end, int esc) {
src = prefix_is_chars(src, beg);
if (!src) return NULL;
char *stop;
while (1) {
if (!*src) return NULL;
stop = prefix_is_chars(src, end);
if (stop && (!esc || *(src-1) != '\\')) return stop;
src = stop ? stop : src+1;
}
}
char *_prefix_alternatives(char *src, ...) {
va_list ap;
va_start(ap, src);
prefix_matcher m = va_arg(ap, prefix_matcher);
char *p = NULL;
while (m && !(p = (*m)(src))) m = va_arg(ap, prefix_matcher);
va_end(ap);
return p;
}
char *_prefix_sequence(char *src, ...) {
va_list ap;
va_start(ap, src);
prefix_matcher m;
while ((m = va_arg(ap, prefix_matcher)) && (src = (*m)(src))) ;
return src;
}
DEFINE_SINGLE_CTYPE_MATCHER(space);
DEFINE_SINGLE_CTYPE_MATCHER(alpha);
DEFINE_SINGLE_CTYPE_MATCHER(digit);
DEFINE_SINGLE_CTYPE_MATCHER(xdigit);
DEFINE_SINGLE_CTYPE_MATCHER(alnum);
DEFINE_SINGLE_CTYPE_MATCHER(punct);
DEFINE_CTYPE_SEQUENCE_MATCHER(space);
DEFINE_CTYPE_SEQUENCE_MATCHER(alpha);
DEFINE_CTYPE_SEQUENCE_MATCHER(digit);
DEFINE_CTYPE_SEQUENCE_MATCHER(xdigit);
DEFINE_CTYPE_SEQUENCE_MATCHER(alnum);
DEFINE_CTYPE_SEQUENCE_MATCHER(punct);
DEFINE_TO_EOL_MATCHER(line_comment, "//");
DEFINE_DELIMITED_MATCHER(block_comment, "/*", "*/", 0);
DEFINE_DELIMITED_MATCHER(double_quoted_string, "\"", "\"", 1);
DEFINE_DELIMITED_MATCHER(single_quoted_string, "\'", "\'", 1);
DEFINE_DELIMITED_MATCHER(interpolant, "#{", "}", 0);
// int main() {
// char *p = prefix_sequence("hello", prefix_is_alphas);
// if (!*p) putchar('0');
// return 0;
// }
\ No newline at end of file
typedef char *(*prefix_matcher)(char *);
#define DECLARE_MATCHER(name) \
char *prefix_is_ ## name(char *)
#define DEFINE_CHARS_MATCHER(name, prefix) \
char *prefix_is_ ## name(char *src) { \
return prefix_is_chars(src, prefix); \
}
#define DEFINE_SINGLE_CTYPE_MATCHER(type) \
char *prefix_is_ ## type(char *src) { \
return is ## type(*src) ? src+1 : NULL; \
}
#define DEFINE_CTYPE_SEQUENCE_MATCHER(type) \
char *prefix_is_ ## type ## s(char *src) { \
char *p = src; \
while (is ## type(*p)) p++; \
return p == src ? NULL : p; \
}
#define DEFINE_TO_EOL_MATCHER(name, prefix) \
char *prefix_is_ ## name(char *src) { \
if (!(src = prefix_is_chars(src, prefix))) return NULL; \
while(*src && *src != '\n') src++; \
return src; \
}
#define DEFINE_DELIMITED_MATCHER(name, begin, end, escapable) \
char *prefix_is_ ## name(char *src) { \
return prefix_is_delimited_by(src, begin, end, escapable); \
}
char *prefix_is_char(char *src, char pre);
char *prefix_is_chars(char *src, char *pre);
char *prefix_is_one_of(char *src, char *class);
char *prefix_is_some_of(char *src, char *class);
char *prefix_is_delimited_by(char *src, char *beg, char *end, int esc);
char *_prefix_alternatives(char *src, ...);
#define prefix_alternatives(src, ...) _prefix_alternatives(src, __VA_ARGS__, NULL)
char *_prefix_sequence(char *src, ...);
#define prefix_sequence(src, ...) _prefix_sequence(src, __VA_ARGS__, NULL)
DECLARE_MATCHER(space);
DECLARE_MATCHER(alpha);
DECLARE_MATCHER(digit);
DECLARE_MATCHER(xdigit);
DECLARE_MATCHER(alnum);
DECLARE_MATCHER(punct);
DECLARE_MATCHER(spaces);
DECLARE_MATCHER(alphas);
DECLARE_MATCHER(digits);
DECLARE_MATCHER(xdigits);
DECLARE_MATCHER(alnums);
DECLARE_MATCHER(puncts);
DECLARE_MATCHER(line_comment);
DECLARE_MATCHER(block_comment);
DECLARE_MATCHER(double_quoted_string);
DECLARE_MATCHER(single_quoted_string);
DECLARE_MATCHER(interpolant);
\ No newline at end of file
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "prefix_primitives.h"
#define test1(name, v1) t1(#name, name, v1)
#define test2(name, v1, v2) t2(#name, name, v1, v2)
void print_slice(char *s, char *t) {
if (t) {
printf("matched %ld characters:\t", t - s);
while (s < t) putchar(*s++);
putchar('\n');
}
else {
printf("matched nothing\n");
}
}
void t1(char *name, char *(*matcher)(char *), char *src) {
printf("testing %s(\"%s\")\n", name, src);
print_slice(src, matcher(src));
putchar('\n');
}
void t2(char *name, char *(*matcher)(char *, char *), char *src, char *pre) {
printf("testing %s(\"%s\", \"%s\")\n", name, src, pre);
print_slice(src, matcher(src, pre));
putchar('\n');
}
int main() {
char *r = "\"blah blah \\\" blah\"";
char *s = "'this \\'is\\' a \"string\" now' blah blah blah";
char *t = "/* this is a c comment \\*/ blah blah";
char *u = "#{ this is an interpolant \\} blah blah";
char *v = "hello my name is aaron";
char *w = "_identifier123";
char *x = "12non_ident_ifier_";
char *y = "-blah-blah_blah";
char *z = "#foo > :first-child { color: #abcdef; }";
char *line_comment = "// blah blah blah // end\n blah blah";
char *stuff = "badec4669264hello";
// test2(prefix_is_char, v, 'h');
// test2(prefix_is_char, v, 'a');
print_slice(v, prefix_is_char(v, 'h'));
print_slice(v, prefix_is_char(v, 'a'));
putchar('\n');
test2(prefix_is_chars, v, "hello");
test2(prefix_is_chars, v, "hello world");
test2(prefix_is_one_of, v, "abcdefgh");
test2(prefix_is_one_of, v, "ijklmnop");
test2(prefix_is_some_of, w, "_deint");
test2(prefix_is_some_of, w, "abcd");
test1(prefix_is_block_comment, t);
test1(prefix_is_block_comment, line_comment);
test1(prefix_is_double_quoted_string, r);
test1(prefix_is_double_quoted_string, s);
test1(prefix_is_single_quoted_string, s);
test1(prefix_is_single_quoted_string, r);
test1(prefix_is_interpolant, u);
test1(prefix_is_interpolant, z);
test1(prefix_is_line_comment, line_comment);
test1(prefix_is_line_comment, t);
char *p = prefix_sequence(stuff, prefix_is_alphas, prefix_is_digits);
print_slice(stuff, _prefix_sequence(stuff, prefix_is_alphas, prefix_is_digits, NULL));
print_slice(stuff, prefix_sequence(stuff, prefix_is_alphas, prefix_is_puncts));
// printn(s, prefix_is_string(s));
// printn(s, prefix_is_one_of(s, "abcde+'"));
// printn(s, prefix_is_some_of(s, "'abcdefghijklmnopqrstuvwxyz "));
// printn(t, prefix_is_block_comment(t));
// printn(u, prefix_is_interpolant(u));
// printn(v, prefix_is_alphas(v));
// printn(v, prefix_is_alpha(v));
// printn(v, prefix_is_exactly(v, "hello"));
// printn(x, prefix_sequence(x, prefix_is_digits, prefix_is_alphas));
// printn(x, prefix_alternatives(x, prefix_is_hyphen, prefix_is_alphas, prefix_is_puncts, prefix_is_digits));
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment