kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

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 }