features_test.c (2439B)
1 #include "generated_features.h" 2 3 #include <ctype.h> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <string.h> 7 8 typedef struct { const char *s; size_t i; } Lexer; 9 10 static int lex_next(Lexer *lx, KitGramToken *out) { 11 while (lx->s[lx->i] && isspace((unsigned char)lx->s[lx->i])) lx->i++; 12 char c = lx->s[lx->i]; 13 if (!c) return 0; 14 15 out->lexeme = &lx->s[lx->i]; 16 out->len = 1; 17 out->line = 1; 18 out->col = (uint32_t)(lx->i + 1); 19 20 if (isdigit((unsigned char)c)) { 21 size_t j = lx->i; 22 while (isdigit((unsigned char)lx->s[j])) j++; 23 out->kind = FEATURES_TOK_NUMBER; 24 out->len = j - lx->i; 25 lx->i = j; 26 return 1; 27 } 28 if (isalpha((unsigned char)c)) { 29 size_t j = lx->i; 30 while (isalnum((unsigned char)lx->s[j]) || lx->s[j] == '_') j++; 31 size_t len = j - lx->i; 32 if (len == 5 && strncmp(&lx->s[lx->i], "while", 5) == 0) 33 out->kind = FEATURES_TOK_WHILE; 34 else if (len == 8 && strncmp(&lx->s[lx->i], "for_each", 8) == 0) 35 out->kind = FEATURES_TOK_FOR_EACH; 36 else 37 out->kind = FEATURES_TOK_IDENT; 38 out->len = len; 39 lx->i = j; 40 return 1; 41 } 42 43 lx->i++; 44 switch (c) { 45 case ',': out->kind = FEATURES_TOK_COMMA; break; 46 case ';': out->kind = FEATURES_TOK_SEMI; break; 47 default: out->kind = FEATURES_TOK__COUNT; break; 48 } 49 return 1; 50 } 51 52 static int accepts(const char *src) { 53 KitGramParser ps; 54 KitGramSlot ctl[128]; 55 KitGramSem vals[128]; 56 KitGramConfig cfg = { .ctl_stack = ctl, .ctl_cap = 128, .val_stack = vals, .val_cap = 128 }; 57 features_parser_init(&ps, &cfg); 58 59 Lexer lx = { src, 0 }; 60 KitGramToken t; 61 while (lex_next(&lx, &t)) 62 if (kit_gram_parser_push(&ps, t) == KIT_GRAM_PARSE_ERROR) return 0; 63 return kit_gram_parser_finish(&ps) == KIT_GRAM_PARSE_ACCEPT; 64 } 65 66 static void check(const char *src, int want) { 67 int got = accepts(src); 68 printf("%s %-18s -> %s\n", got == want ? "ok " : "FAIL", src, got ? "accept" : "reject"); 69 if (got != want) { 70 printf("FAILED -- feature grammar mismatch\n"); 71 exit(1); 72 } 73 } 74 75 int main(void) { 76 printf("== generated EBNF feature parser ==\n"); 77 check("while 1; a", 1); 78 check("for_each 1,2,3; a b c", 1); 79 check("while 1,2,3,; a b", 1); 80 check("while 1,,; a", 0); 81 check("for_each 1,2;", 0); 82 check("repeat 1; a", 0); 83 return 0; 84 }