Skip to content

Instantly share code, notes, and snippets.

@mashingan
Last active November 13, 2022 21:46
Show Gist options
  • Save mashingan/2e14c9f219cc8a6fb184d8a27d55bde9 to your computer and use it in GitHub Desktop.
Save mashingan/2e14c9f219cc8a6fb184d8a27d55bde9 to your computer and use it in GitHub Desktop.

Revisions

  1. mashingan revised this gist Nov 13, 2022. 1 changed file with 30 additions and 4 deletions.
    34 changes: 30 additions & 4 deletions declare.c
    Original file line number Diff line number Diff line change
    @@ -112,10 +112,24 @@ char* fetchFunc(char *s, struct syms *thesym) {
    char *fetchArray(char *s, struct syms *thesym) {
    char *st = s;
    thesym->modifier = ModArray;
    thesym->arrval.size = 0;
    removeWhiteSpaces(st);
    removeAorAn(st);
    char *stt = strchr(st, ' ');
    if (!stt) return s;
    char buf[10];
    #if DEBUG
    printf("stt: %s\n", stt);
    char temp[stt-st+2];
    memcpy(temp, st, stt-st);
    temp[stt-st+1] = '\0';
    printf("temp arr: %s\n", temp);
    #endif
    for (char *st2 = st; st2 < stt; st2++) {
    if (!isdigit(*st2)) {
    return s;
    }
    }
    memcpy(buf, st, stt-st);
    thesym->arrval.size = atoi(buf);
    return stt;
    @@ -157,13 +171,25 @@ enum modifier parse(char **s, struct syms* thesym) {
    char *ss = *s;
    char typename[10];
    if ((ss = isFunc(*s)) > *s) {
    #if DEBUG
    printf("parse got func\n");
    #endif
    *s = fetchFunc(ss, thesym);
    } else if ((ss = isArray(*s)) > *s) {
    #if DEBUG
    printf("parse got array\n");
    #endif
    *s = fetchArray(ss, thesym);
    } else if ((ss = isPtr(*s)) > *s) {
    #if DEBUG
    printf("parse got pointer\n");
    #endif
    thesym->modifier = ModPtr;
    *s = ss;
    } else if ((ss = isStruct(*s)) > *s) {
    #if DEBUG
    printf("parse got struct\n");
    #endif
    *s = fetchStruct(ss, thesym);
    } else if ((ss = isType(*s, typename, 10)) > *s) {
    thesym->modifier = ModPlain;
    @@ -258,9 +284,9 @@ char* translate(struct syms symbs[], int symlen, char *varname, char* out[], int
    int outlen = strlen(*out);
    memcpy(temp, *out, outlen);
    if (sym.arrval.size == 0) {
    sprintf(*out, "(%s)[]", temp);
    sprintf(*out, "%s[]", temp);
    } else {
    sprintf(*out, "(%s)[%d]", temp, sym.arrval.size);
    sprintf(*out, "%s[%d]", temp, sym.arrval.size);
    }
    memset(temp, 0, outlen);
    } else if (sym.modifier == ModPlain) {
    @@ -298,8 +324,8 @@ char* translate(struct syms symbs[], int symlen, char *varname, char* out[], int
    //#define sample "z is a pointer to a struct of type a_struct."
    //#define sample "zk is a pointer to function that return int."
    //#define sample "zz is a pointer to function that return pointer to int."
    //#define sample "x is a pointer to an array of 10 pointers to functions that return pointer to struct of type resfunc."
    #define sample "x is a pointer to function that return pointer to function that return pointer to int."
    #define sample "x is a pointer to an array of 10 pointers to functions that return pointer to struct of type resfunc."
    //#define sample "x is a pointer to function that return pointer to function that return pointer to int."

    int main(int argc, char *argv[]) {
    #define buflen 512
  2. mashingan revised this gist Nov 13, 2022. 1 changed file with 349 additions and 0 deletions.
    349 changes: 349 additions & 0 deletions declare.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,349 @@
    #include <ctype.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include "declare.h"

    char* isFunc(char *s) {
    char *ss = s;
    removeWhiteSpaces(ss);
    removeAorAn(ss);
    if (strstr(ss, func) == ss) {
    ss = strstr(ss, "rn"); // that retu'rn'[s]
    ss += 2;
    if (ss && *ss == 's') ss++;
    return ss;
    }
    return s;
    }

    char* isArray(char *s) {
    char *ss = s;
    removeWhiteSpaces(ss);
    removeAorAn(ss);
    if (strstr(ss, arrayof) == ss) {
    ss = strstr(ss, "of ");
    ss += 3;
    return ss;
    }
    return s;
    }

    char* isStruct(char *s) {
    char *ss = s;
    removeWhiteSpaces(ss);
    removeAorAn(ss);
    if (strstr(ss, structof) == ss) {
    ss = strstr(ss, "ype ");
    ss += 4;
    return ss;
    }
    return s;
    }

    char *isPtr(char *s) {
    char *ss = s;
    removeWhiteSpaces(ss);
    removeAorAn(ss);
    if (strstr(ss, ptrto) == ss) {
    ss = strstr(ss, "to ");
    ss += 3;
    return ss;
    }
    return s;
    }

    char* var(char *s, char* name, int namelen) {
    char *ss = s;
    char *sc;
    removeWhiteSpaces(ss);
    removeAorAn(ss);
    if ((sc = strstr(ss, "is a")) > ss) {
    for (int i = 0; i < namelen && !isspace(ss[i]); i++) {
    name[i] = ss[i];
    }
    sc += 4;
    if (sc && *sc == 'n') sc++;
    return sc;
    }
    return s;
    }

    char* isType(char *s, char* typename, int typelen) {
    char *ss = s;
    char *sc;
    removeWhiteSpaces(ss);
    removeAorAn(ss);
    memset(typename, 0, typelen);
    if (strstr(ss, "int") == ss) {
    memcpy(typename, "int", 3);
    ss += 3;
    } else if (strstr(ss, "void") == ss) {
    memcpy(typename, "void", 4);
    ss += 4;
    } else if (strstr(ss, "char") == ss) {
    memcpy(typename, "char", 4);
    ss += 4;
    } else if (strstr(ss, "float") == ss) {
    memcpy(typename, "float", 5);
    ss += 5;
    } else if (strstr(ss, "double") == ss) {
    memcpy(typename, "double", 6);
    ss += 6;
    } else {
    return s;
    }
    while(!isspace(*ss)) {
    ss++;
    if (*ss == '.') break;
    }
    return ss;
    }

    char* fetchFunc(char *s, struct syms *thesym) {
    thesym->modifier = ModFunc;
    char *ss = s;
    /*
    thesym->fnc.ret = malloc(sizeof(struct syms));
    parse(&ss, thesym->fnc.ret);
    */
    return ss;
    }
    char *fetchArray(char *s, struct syms *thesym) {
    char *st = s;
    thesym->modifier = ModArray;
    removeWhiteSpaces(st);
    removeAorAn(st);
    char *stt = strchr(st, ' ');
    char buf[10];
    memcpy(buf, st, stt-st);
    thesym->arrval.size = atoi(buf);
    return stt;
    }

    char *fetchStruct(char *s, struct syms *thesym) {
    thesym->modifier = ModStruct;
    #if DEBUG
    printf("*s fetchStruct: %s\n", s);
    #endif
    char *ss = s;
    #define structnamelen 20
    char typename[structnamelen];
    int typelen = 0;
    if (isType(ss, typename, structnamelen) > ss) {
    typelen = strlen(typename);
    memcpy(thesym->stcval.thetype, typename, typelen);
    } else {
    removeWhiteSpaces(ss);
    for (int i = 0; i < structnamelen && ss[i] && !isspace(ss[i]); i++, typelen++) {
    if (ss[i] == '.') break;
    thesym->stcval.thetype[i] = ss[i];
    }
    if (typelen < structnamelen) {
    thesym->stcval.thetype[typelen] = '\0';
    }
    s = ss;
    }
    #undef structnamelen
    return s + typelen;
    }

    char *fetchPtr(char *s, struct syms *thesym) {
    thesym->modifier = ModPtr;
    return s;
    }

    enum modifier parse(char **s, struct syms* thesym) {
    char *ss = *s;
    char typename[10];
    if ((ss = isFunc(*s)) > *s) {
    *s = fetchFunc(ss, thesym);
    } else if ((ss = isArray(*s)) > *s) {
    *s = fetchArray(ss, thesym);
    } else if ((ss = isPtr(*s)) > *s) {
    thesym->modifier = ModPtr;
    *s = ss;
    } else if ((ss = isStruct(*s)) > *s) {
    *s = fetchStruct(ss, thesym);
    } else if ((ss = isType(*s, typename, 10)) > *s) {
    thesym->modifier = ModPlain;
    memset(thesym->typeplain, 0, 10);
    memcpy(thesym->typeplain, typename, strlen(typename));
    *s = ss;
    } else {
    thesym->modifier = ModEnd;
    }
    return thesym->modifier;
    }


    void checkSyms(struct syms *thesym) {
    if (!thesym) return;
    printf("modifier: %s", modstring[thesym->modifier]);
    switch (thesym->modifier) {
    case ModPlain:
    printf(" with type: %s\n", thesym->typeplain);
    break;
    case ModArray:
    printf(" with size: %d\n", thesym->arrval.size);
    break;
    case ModPtr:
    printf("^\n");
    break;
    case ModStruct:
    printf(" of type %s\n", thesym->stcval.thetype);
    break;
    case ModEnd:
    printf(";\n");
    break;
    case ModFunc:
    printf(" return "); //checkSyms(thesym->fnc.ret);
    printf("\n");
    break;
    default:
    printf("\n");
    break;

    }
    }

    void freesyms(struct syms *thesym) {
    if (!thesym) return;
    if (thesym->modifier == ModFunc)
    freefnc(thesym->fnc);
    else
    free(thesym);
    }

    void freefnc(struct fnc fnc) {
    freesyms(fnc.args);
    freesyms(fnc.ret);
    }

    char* translate(struct syms symbs[], int symlen, char *varname, char* out[], int buflen) {
    sprintf(*out, "%s", varname);
    #if DEBUG
    printf("the current out: %s from varname %s\n", *out, varname);
    #endif
    struct syms *thetype = NULL;
    char temp[buflen];
    memset(temp, 0, buflen);
    for (int i = 0; i < symlen; i++) {
    struct syms sym = symbs[i];
    if (sym.modifier == ModPtr) {
    #if DEBUG
    printf("got pointer\n");
    #endif
    int outlen = strlen(*out);
    memcpy(temp, *out, outlen);
    sprintf(*out, "(*%s)", temp);
    memset(temp, 0, outlen);
    } else if (sym.modifier == ModStruct) {
    #if DEBUG
    printf("got struct\n");
    #endif
    int outlen = strlen(*out);
    memcpy(temp, *out, outlen);
    sprintf(*out, "struct %s %s", sym.stcval.thetype, temp);
    memset(temp, 0, outlen);
    } else if (sym.modifier == ModEnd) {
    #if DEBUG
    printf("got end\n");
    #endif
    strcat(*out, ";");
    } else if (sym.modifier == ModArray) {
    #if DEBUG
    printf("got array\n");
    #endif
    int outlen = strlen(*out);
    memcpy(temp, *out, outlen);
    if (sym.arrval.size == 0) {
    sprintf(*out, "(%s)[]", temp);
    } else {
    sprintf(*out, "(%s)[%d]", temp, sym.arrval.size);
    }
    memset(temp, 0, outlen);
    } else if (sym.modifier == ModPlain) {
    #if DEBUG
    printf("got plain type\n");
    #endif
    thetype = &symbs[i];
    } else if (sym.modifier == ModFunc) {
    #if DEBUG
    printf("got func\n");
    #endif
    int outlen = strlen(*out);
    memcpy(temp, *out, outlen);
    sprintf(*out, "%s()", temp);
    memset(temp, 0, outlen);
    }
    #if DEBUG
    printf("the current out: %s\n", *out);
    #endif
    }
    if (thetype) {
    int outlen = strlen(*out);
    memcpy(temp, *out, outlen);
    sprintf(*out, "%s %s", thetype->typeplain, temp);
    }
    #if DEBUG
    printf("the current out: %s\n", *out);
    #endif
    return *out;
    }

    //#define sample "y is an array of 10 floats."
    //#define sample "y is a float."
    //#define sample "y is an array of 10 pointers to floats."
    //#define sample "z is a pointer to a struct of type a_struct."
    //#define sample "zk is a pointer to function that return int."
    //#define sample "zz is a pointer to function that return pointer to int."
    //#define sample "x is a pointer to an array of 10 pointers to functions that return pointer to struct of type resfunc."
    #define sample "x is a pointer to function that return pointer to function that return pointer to int."

    int main(int argc, char *argv[]) {
    #define buflen 512
    //char bufout[buflen];
    char *bufout = malloc(buflen);
    char *input = sample;
    if (argc > 1) {
    input = malloc(buflen);
    memcpy(input, argv[1], buflen);
    }
    char *initialinput = input;
    printf("input is '%s'\n", input);
    char varname[10];
    memset(varname, '\0', 10);
    char *newinput = var(input, varname, 10);
    struct syms symbs[10];
    if (newinput == input) {
    perror("Invalid variable assignment");
    exit(1);
    }
    input = newinput;
    int symcount = 0;
    enum modifier parsemod = ModPlain;
    while(input && symcount < 10 && parsemod != ModEnd) {
    parsemod = parse(&input, &symbs[symcount]);
    #if DEBUG
    checkSyms(&symbs[symcount]);
    printf("count %2d now input '%s'\n", symcount, input);
    #endif
    symcount++;
    }
    #if DEBUG
    printf("varname is '%s' with rest of input is '%s' and input after parse '%s'\n",
    varname, newinput, input);
    #endif
    translate(symbs, symcount, varname, &bufout, buflen);
    printf("the translation from '%s' is '%s'\n", initialinput, bufout);
    for (int i = 0; i < 10; i++) {
    if (symbs[i].modifier == ModFunc) {
    freefnc(symbs[i].fnc);
    }
    }
    free(bufout);
    free(input);
    #undef buflen
    return 0;
    }
  3. mashingan created this gist Nov 13, 2022.
    73 changes: 73 additions & 0 deletions declare.h
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,73 @@
    #define arrayof "array"
    #define ptrto "pointer"
    #define func "function"
    #define structof "struct"

    #define removeWhiteSpaces(ss) while(isspace(*(ss))) (ss)++
    #define removeAorAn(ss) if (*(ss) == 'a' && (ss)[1] == 'n') {\
    (ss) += 2; removeWhiteSpaces(ss);\
    } else if (*(ss) == 'a' && (ss)[1] == ' ') {\
    (ss)++; removeWhiteSpaces((ss));\
    }

    enum modifier {
    ModPlain,
    ModPtr,
    ModArray,
    ModFunc,
    ModStruct,
    ModEnum,
    ModEnd,
    };

    static const char *modstring[] = {"Plain Type",
    "Pointer",
    "Array",
    "Function",
    "Struct",
    "Enum",
    "End",
    };

    struct arr {
    int size;
    };

    struct stc {
    char thetype[20];
    };

    struct fnc {
    struct syms *args;
    struct syms *ret;
    };

    struct syms {
    enum modifier modifier;
    union {
    char typeplain[10];
    struct fnc fnc;
    struct arr arrval;
    struct stc stcval;
    };
    };

    char* isFunc(char *s);
    char* isArray(char *s);
    char* isStruct(char *s);
    char* isPtr(char *s);
    char* var(char *s, char*, int);
    char* isType(char *s, char*, int);
    enum modifier parse(char **s, struct syms*);

    char* fetchFunc(char *s, struct syms*);
    char* fetchArray(char *s, struct syms*);
    char* fetchStruct(char *s, struct syms*);
    char* fetchPtr(char *s, struct syms*);

    void checkSyms(struct syms *thesym);

    void freesyms(struct syms *thesym);
    void freefnc(struct fnc fnc);

    char* translate(struct syms[], int, char*, char*[], int);