#include #include #include #include #define MAX_DELKA 1000 typedef char token; /* Typ tokenu -- +, -, *, /, (, ), 'a' pro proměnnou, '0' pro číslo. */ char vstup[MAX_DELKA]; char tokeny[MAX_DELKA]; char *val[MAX_DELKA]; /* Pro proměnné a čísla řetězce, obsahující jejich hodnotu. */ void lex (void) { /*{\bo Lexikálni analýza}*/ unsigned index = 0, atok = 0, zac; char znak; while (1) { znak = vstup[index++]; while (isspace(znak)) znak = vstup[index++]; /* Přeskočíme mezery. */ switch (znak) { case 0: /* Na konec výrazu si přidáme zavírací závorku,*/ tokeny[atok++] = ')'; return; /* abychom ho nemuseli ošetřovat speciálně. */ case '+': case '-': case '*': case '/': case '(': case ')': tokeny[atok++] = znak; break; default: zac = index - 1; if (isdigit (znak)) { tokeny[atok] = 'a'; while (isdigit (znak = vstup[index])) index++; } else if (isalpha (znak)) { tokeny[atok] = '0'; while (isalnum (znak = vstup[index])) index++; } else abort (); vstup[index] = 0; val[atok++] = strdup (vstup + zac); vstup[index] = znak; break; } } } char *vyhodnot (char *levy, char znam, char *pravy) { /*{\bo Syntaktická a semantická analýza}*/ static unsigned pom = 0; char *prom = malloc (20); sprintf (prom, "_tmp%d", pom++); printf ("assign %s (%s %c %s)\n", prom, levy, znam, pravy); return prom; } unsigned pos; /* Aktuálni pozice ve vstupu. */ char *cti_term (void); char *cti_faktor (void); char *cti_vyraz (void) { char *levy, *pravy, znam; levy = cti_faktor (); while (1) { /* Čteme zbývající faktory až do konce výrazu či závorky. */ if (tokeny[pos] == ')') return levy; znam = tokeny[pos++]; pravy = cti_faktor (); levy = vyhodnot (levy, znam, pravy); } } char *cti_faktor (void) { char *levy, *pravy, znam; levy = cti_term (); while (1) { znam = tokeny[pos]; if (znam != '*' && znam != '/') return levy; pos++; pravy = cti_term (); levy = vyhodnot (levy, znam, pravy); } } char *cti_term (void) { char *hodnota, token = tokeny[pos++]; if (token == '(') { hodnota = cti_vyraz (); /* Přeskočit zavírací závorku. */ pos++; } else hodnota = val[pos - 1]; return hodnota; } int main(void) { /*{\bo A teď to celé spojíme dohromady}*/ char *hodnota; fgets (vstup, MAX_DELKA, stdin); lex (); hodnota = cti_vyraz (); printf ("assign _result %s\n", hodnota); return 0; }