Commit 027a020d by Aaron Leung

Pulling stuff out and simplifying.

parent 093aee42
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include "prefix.h"
char *sass_prefix_is_char(char *src, char pre) {
return pre == *src ? src+1 : NULL;
}
char *sass_prefix_is_chars(char *src, char *pre) {
while (*pre && *src == *pre) src++, pre++;
return *pre ? NULL : src;
}
char *sass_prefix_is_one_of(char *src, char *class) {
while(*class && *src != *class) class++;
return *class ? src+1 : NULL;
}
char *sass_prefix_is_some_of(char *src, char *class) {
char *p = src;
while(sass_prefix_is_one_of(p, class)) p++;
return p == src ? NULL : p;
}
char *sass_prefix_is_delimited_by(char *src, char *beg, char *end, int esc) {
src = sass_prefix_is_chars(src, beg);
if (!src) return NULL;
char *stop;
while (1) {
if (!*src) return NULL;
stop = sass_prefix_is_chars(src, end);
if (stop && (!esc || *(src-1) != '\\')) return stop;
src = stop ? stop : src+1;
}
}
char *sass_prefix_epsilon(char *src) {
return src;
}
char *sass_prefix_not(char *src, sass_prefix_matcher m) {
return m(src) ? NULL : src;
}
char *_sass_prefix_alternatives(char *src, ...) {
va_list ap;
va_start(ap, src);
sass_prefix_matcher m = va_arg(ap, sass_prefix_matcher);
char *p = NULL;
while (m && !(p = (*m)(src))) m = va_arg(ap, sass_prefix_matcher);
va_end(ap);
return p;
}
char *_sass_prefix_sequence(char *src, ...) {
va_list ap;
va_start(ap, src);
sass_prefix_matcher m;
while ((m = va_arg(ap, sass_prefix_matcher)) && (src = (*m)(src))) ;
return src;
}
char *sass_prefix_optional(char *src, sass_prefix_matcher m) {
char *p = m(src);
return p ? p : src;
}
char *sass_prefix_zero_plus(char *src, sass_prefix_matcher m) {
char *p = m(src);
while(p) src = p, p = m(src);
return src;
}
char *sass_prefix_one_plus(char *src, sass_prefix_matcher m) {
char *p = m(src);
if (!p) return NULL;
while(p) src = p, p = m(src);
return src;
}
char *sass_prefix_find_first(char *src, sass_prefix_matcher m) {
while (*src && !m(src)) src++;
return *src ? src : NULL;
}
SINGLE_CTYPE_MATCHER(space);
SINGLE_CTYPE_MATCHER(alpha);
SINGLE_CTYPE_MATCHER(digit);
SINGLE_CTYPE_MATCHER(xdigit);
SINGLE_CTYPE_MATCHER(alnum);
SINGLE_CTYPE_MATCHER(punct);
CTYPE_SEQUENCE_MATCHER(space);
CTYPE_SEQUENCE_MATCHER(alpha);
CTYPE_SEQUENCE_MATCHER(digit);
CTYPE_SEQUENCE_MATCHER(xdigit);
CTYPE_SEQUENCE_MATCHER(alnum);
CTYPE_SEQUENCE_MATCHER(punct);
TO_EOL_MATCHER(line_comment, "//");
DELIMITED_MATCHER(block_comment, "/*", "*/", 0);
DELIMITED_MATCHER(double_quoted_string, "\"", "\"", 1);
DELIMITED_MATCHER(single_quoted_string, "\'", "\'", 1);
DELIMITED_MATCHER(interpolant, "#{", "}", 0);
CHAR_MATCHER (lparen, '(');
CHAR_MATCHER (rparen, ')');
CHAR_MATCHER (lbrack, '[');
CHAR_MATCHER (rbrack, ']');
CHAR_MATCHER (lbrace, '{');
CHAR_MATCHER (rbrace, '}');
CHAR_MATCHER (underscore, '_');
CHAR_MATCHER (hyphen, '-');
CHAR_MATCHER (semicolon, ';');
CHAR_MATCHER (colon, ':');
CHAR_MATCHER (period, '.');
CHAR_MATCHER (dot, '.');
CHAR_MATCHER (question, '?');
CHAR_MATCHER (exclamation, '!');
CHAR_MATCHER (tilde, '~');
CHAR_MATCHER (backquote, '`');
CHAR_MATCHER (quote, '\"');
CHAR_MATCHER (apostrophe, '\'');
CHAR_MATCHER (ampersand, '&');
CHAR_MATCHER (caret, '^');
CHAR_MATCHER (pipe, '|');
CHAR_MATCHER (slash, '/');
CHAR_MATCHER (backslash, '\\');
CHAR_MATCHER (asterisk, '*');
CHAR_MATCHER (star, '*');
CHAR_MATCHER (pound, '#');
CHAR_MATCHER (hash, '#');
CHAR_MATCHER (plus, '+');
CHAR_MATCHER (minus, '-');
CHAR_MATCHER (times, '*');
CHAR_MATCHER (divide, '/');
CHAR_MATCHER (percent, '%');
CHAR_MATCHER (dollar, '$');
CHAR_MATCHER (gt, '>');
CHARS_MATCHER(gte, ">=");
CHAR_MATCHER (lt, '<');
CHARS_MATCHER(lte, "<=");
CHAR_MATCHER (eq, '=');
CHAR_MATCHER (assign, '=');
CHARS_MATCHER(equal, "==");
CHAR_MATCHER (exactmatch, '=');
CHARS_MATCHER(includes, "~=");
CHARS_MATCHER(dashmatch, "|=");
CHARS_MATCHER(prefixmatch, "^=");
CHARS_MATCHER(suffixmatch, "$=");
CHARS_MATCHER(substringmatch, "*=");
static OPTIONAL_MATCHER(optional_hyphen, sass_prefix_is_hyphen);
static ALTERNATIVES_MATCHER(nmchar, sass_prefix_is_alnums, sass_prefix_is_underscore, sass_prefix_is_hyphen);
static ALTERNATIVES_MATCHER(nmstart, sass_prefix_is_alphas, sass_prefix_is_underscore);
static SEQUENCE_MATCHER(identstart, sass_prefix_is_optional_hyphen, sass_prefix_is_nmstart);
ONE_PLUS_MATCHER(name, sass_prefix_is_nmchar);
FIRST_REST_MATCHER(identifier, sass_prefix_is_identstart, sass_prefix_is_nmchar);
static OPTIONAL_MATCHER(optional_digits, sass_prefix_is_digits);
static SEQUENCE_MATCHER(realnum, sass_prefix_is_optional_digits, sass_prefix_is_dot, sass_prefix_is_digits);
ALTERNATIVES_MATCHER(number, sass_prefix_is_digits, sass_prefix_is_realnum);
ALTERNATIVES_MATCHER(string, sass_prefix_is_double_quoted_string, sass_prefix_is_single_quoted_string);
SEQUENCE_MATCHER(idname, sass_prefix_is_hash, sass_prefix_is_name);
SEQUENCE_MATCHER(classname, sass_prefix_is_dot, sass_prefix_is_identifier);
SEQUENCE_MATCHER(function, sass_prefix_is_identifier, sass_prefix_is_lparen);
static OPTIONAL_MATCHER(optional_spaces, sass_prefix_is_spaces);
SEQUENCE_MATCHER(adjacent_to, sass_prefix_is_optional_spaces, sass_prefix_is_plus);
SEQUENCE_MATCHER(precedes, sass_prefix_is_optional_spaces, sass_prefix_is_tilde);
SEQUENCE_MATCHER(parent_of, sass_prefix_is_optional_spaces, sass_prefix_is_gt);
char *sass_prefix_is_ancestor_of(char *src) {
char *p = src;
while (isspace(*p)) p++;
return p == src ? NULL : p;
}
\ No newline at end of file
typedef char *(*sass_prefix_matcher)(char *);
#define DECLARE(name) \
char *sass_prefix_is_ ## name(char *)
#define ALIAS_MATCHERS(orig, new) \
char *(*new)(char *) = orig
#define CHAR_MATCHER(name, prefix) \
char *sass_prefix_is_ ## name(char *src) { \
return sass_prefix_is_char(src, prefix); \
}
#define CHARS_MATCHER(name, prefix) \
char *sass_prefix_is_ ## name(char *src) { \
return sass_prefix_is_chars(src, prefix); \
}
#define CHAR_CLASS_MATCHER(name, class) \
char *sass_prefix_is_ ## name(char *src) { \
return sass_prefix_is_one_of(src, class); \
}
#define CHARS_CLASS_MATCHER(name, class) \
char *sass_prefix_is_ ## name(char *src) { \
return sass_prefix_is_some_of(src, class); \
}
#define SINGLE_CTYPE_MATCHER(type) \
char *sass_prefix_is_ ## type(char *src) { \
return is ## type(*src) ? src+1 : NULL; \
}
#define CTYPE_SEQUENCE_MATCHER(type) \
char *sass_prefix_is_ ## type ## s(char *src) { \
char *p = src; \
while (is ## type(*p)) p++; \
return p == src ? NULL : p; \
}
#define TO_EOL_MATCHER(name, prefix) \
char *sass_prefix_is_ ## name(char *src) { \
if (!(src = sass_prefix_is_chars(src, prefix))) return NULL; \
while(*src && *src != '\n') src++; \
return src; \
}
#define DELIMITED_MATCHER(name, begin, end, escapable) \
char *sass_prefix_is_ ## name(char *src) { \
return sass_prefix_is_delimited_by(src, begin, end, escapable); \
}
#define ALTERNATIVES_MATCHER(name, ...) \
char *sass_prefix_is_ ## name(char *src) { \
return sass_prefix_alternatives(src, __VA_ARGS__); \
}
#define SEQUENCE_MATCHER(name, ...) \
char *sass_prefix_is_ ## name(char *src) { \
return sass_prefix_sequence(src, __VA_ARGS__); \
}
#define OPTIONAL_MATCHER(name, matcher) \
char *sass_prefix_is_ ## name(char *src) { \
return sass_prefix_optional(src, matcher); \
}
#define ZERO_PLUS_MATCHER(name, matcher) \
char *sass_prefix_is_ ## name(char *src) { \
return sass_prefix_zero_plus(src, matcher); \
}
#define ONE_PLUS_MATCHER(name, matcher) \
char *sass_prefix_is_ ## name(char *src) { \
return sass_prefix_one_plus(src, matcher); \
}
#define FIRST_REST_MATCHER(name, first_matcher, rest_matcher) \
char *sass_prefix_is_ ## name(char *src) { \
if (src = first_matcher(src)) src = sass_prefix_zero_plus(src, rest_matcher); \
return src; \
}
char *sass_prefix_is_char(char *src, char pre);
char *sass_prefix_is_chars(char *src, char *pre);
char *sass_prefix_is_one_of(char *src, char *class);
char *sass_prefix_is_some_of(char *src, char *class);
char *sass_prefix_is_delimited_by(char *src, char *beg, char *end, int esc);
char *sass_prefix_epsilon(char *src);
char *sass_prefix_not(char *src, sass_prefix_matcher m);
char *_sass_prefix_alternatives(char *src, ...);
#define sass_prefix_alternatives(src, ...) _sass_prefix_alternatives(src, __VA_ARGS__, NULL)
char *_sass_prefix_sequence(char *src, ...);
#define sass_prefix_sequence(src, ...) _sass_prefix_sequence(src, __VA_ARGS__, NULL)
char *sass_prefix_optional(char *src, sass_prefix_matcher m);
char *sass_prefix_zero_plus(char *src, sass_prefix_matcher m);
char *sass_prefix_one_plus(char *src, sass_prefix_matcher m);
char *sass_prefix_find_first(char *src, sass_prefix_matcher m);
DECLARE(space);
DECLARE(alpha);
DECLARE(digit);
DECLARE(xdigit);
DECLARE(alnum);
DECLARE(punct);
DECLARE(spaces);
DECLARE(alphas);
DECLARE(digits);
DECLARE(xdigits);
DECLARE(alnums);
DECLARE(puncts);
DECLARE(shell_comment);
DECLARE(line_comment);
DECLARE(block_comment);
DECLARE(double_quoted_string);
DECLARE(single_quoted_string);
DECLARE(interpolant);
DECLARE(lparen);
DECLARE(rparen);
DECLARE(lbrack);
DECLARE(rbrack);
DECLARE(lbrace);
DECLARE(rbrace);
DECLARE(underscore);
DECLARE(hyphen);
DECLARE(semicolon);
DECLARE(colon);
DECLARE(period);
DECLARE(dot);
DECLARE(question);
DECLARE(exclamation);
DECLARE(tilde);
DECLARE(backquote);
DECLARE(quote);
DECLARE(apostrophe);
DECLARE(ampersand);
DECLARE(caret);
DECLARE(pipe);
DECLARE(slash);
DECLARE(backslash);
DECLARE(asterisk);
DECLARE(star);
DECLARE(pound);
DECLARE(hash);
DECLARE(plus);
DECLARE(minus);
DECLARE(times);
DECLARE(divide);
DECLARE(percent);
DECLARE(dollar);
DECLARE(gt);
DECLARE(gte);
DECLARE(lt);
DECLARE(lte);
DECLARE(eq);
DECLARE(assign);
DECLARE(equal);
DECLARE(exactmatch);
DECLARE(classmatch);
DECLARE(dashmatch);
DECLARE(prefixmatch);
DECLARE(suffixmatch);
DECLARE(substringmatch);
DECLARE(name);
DECLARE(identifier);
DECLARE(number);
DECLARE(string);
DECLARE(idname);
DECLARE(classname);
DECLARE(functional);
DECLARE(adjacent_to);
DECLARE(parent_of);
DECLARE(precedes);
DECLARE(ancestor_of);
\ No newline at end of file
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "prefix.h"
void print_slice(char *s, char *t) {
if (t) {
printf("succeeded with %ld characters:\t", t - s);
while (s < t) putchar(*s++);
putchar('\n');
}
else {
printf("failed\n");
}
}
#define test1(matcher, src) \
(printf("testing << %s >>\n", #matcher), print_slice(src, matcher(src)))
#define testn(matcher, src, ...) \
(printf("testing << %s >>\n", #matcher), print_slice(src, matcher(src, __VA_ARGS__)))
int main() {
char *spaces = " \t \t \v \r\n \n\nhello world";
char *dqstring = "\"blah blah \\\" blah\"";
char *sqstring = "'this \\'is\\' a \"string\" now' blah blah blah";
char *scomment = "# a shell-style comment";
char *bcomment = "/* this is a c comment \\*/ blah blah";
char *non_comment = "/* blah blah";
char *interpolant = "#{ this is an interpolant \\} blah blah";
char *words = "hello my name is aaron";
char *id1 = "_identifier123{blah bloo}";
char *non_id = "12non_ident_ifier_";
char *word2 = "-blah-bl+ah_bl12-34+1:foobar;";
char *non_word = "-12blah-bloo";
char *selector = "#foo > :first-child { color: #abcdef; }";
char *lcomment = "// blah blah blah // end\n blah blah";
char *id2 = "badec4669264hello";
char *integer1 = "3837483+3";
char *integer2 = "+294739-4";
char *integer3 = "-294729+1";
char *class = ".blah-blah_bloo112-blah+blee4 hello";
char *id = "#foo_bar-baz123-hux blee";
test1(sass_prefix_is_spaces, spaces);
test1(sass_prefix_is_spaces, words);
testn(sass_prefix_is_char, words, 'h');
testn(sass_prefix_is_char, words, 'a');
testn(sass_prefix_is_chars, words, "hello");
testn(sass_prefix_is_chars, words, "hello world");
testn(sass_prefix_is_one_of, words, "abcdefgh");
testn(sass_prefix_is_one_of, words, "ijklmnop");
testn(sass_prefix_is_some_of, id1, "_deint");
testn(sass_prefix_is_some_of, id1, "abcd");
test1(sass_prefix_is_block_comment, bcomment);
test1(sass_prefix_is_block_comment, non_comment);
test1(sass_prefix_is_double_quoted_string, dqstring);
test1(sass_prefix_is_double_quoted_string, sqstring);
test1(sass_prefix_is_single_quoted_string, sqstring);
test1(sass_prefix_is_single_quoted_string, dqstring);
test1(sass_prefix_is_interpolant, interpolant);
test1(sass_prefix_is_interpolant, lcomment);
test1(sass_prefix_is_line_comment, lcomment);
test1(sass_prefix_is_line_comment, non_comment);
test1(sass_prefix_epsilon, words);
testn(sass_prefix_not, words, sass_prefix_is_puncts);
testn(sass_prefix_not, words, sass_prefix_is_alphas);
testn(sass_prefix_sequence, id2, sass_prefix_is_alphas, sass_prefix_is_digits);
testn(sass_prefix_sequence, id2, sass_prefix_is_alphas, sass_prefix_is_puncts);
testn(sass_prefix_optional, non_id, sass_prefix_is_digits);
testn(sass_prefix_optional, words, sass_prefix_is_digits);
testn(sass_prefix_zero_plus, words, sass_prefix_is_alphas);
testn(sass_prefix_zero_plus, non_id, sass_prefix_is_alphas);
testn(sass_prefix_one_plus, words, sass_prefix_is_alphas);
testn(sass_prefix_one_plus, non_id, sass_prefix_is_alphas);
test1(sass_prefix_is_classname, class);
test1(sass_prefix_is_classname, words);
test1(sass_prefix_is_idname, id);
test1(sass_prefix_is_idname, class);
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