#include #include #include #include #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; }