#include #include #include #include #include "lexer.h" token *lex1Token(char *input, int *i); /* враћа показивач на једну token структуру, која означава један одређен токен, чита улазни стринг од i-тог карактера, и мења i тако да оно затим индексира следећи токен или крај стринга*/ token *lexLine(char *input) { int i = 0, n; n = strlen(input); token *root = NULL, **new; new = &root; while (i < n) { *new = lex1Token(input, &i); if ((*new)->type == undefined) { /* уколико се у реду нађе токен који је лексички погрешан, штампа се место тог токена у реду и брише се цела листа, функција враћа NULL*/ fprintf(stderr, "Невалидан токен на месту %d\n", i); new = &root; while (*new != NULL) { free(root->lexeme); new = &((*new)->next); free(root); root = *new; } return NULL; } new = &((*new)->next); } return root; } regex_t regNumber, regSymbol, regParenthesis, regSpace; token *lex1Token(char *input, int *i) { token *result = malloc(sizeof(token)); result->next = NULL; regcomp(®Space, "^[[:space:]]*", REG_EXTENDED); regcomp(®Number, "^[-+]?[[:digit:]]+", REG_EXTENDED); regcomp(®Symbol, "^[-+/*]", REG_EXTENDED); /* за сада подржава само симболе -, +, * и / */ regcomp(®Parenthesis, "^[()]", REG_EXTENDED); const int nmatches = 1; regmatch_t a[nmatches]; regexec(®Space, input + *i, nmatches, a, 0); *i += a[0].rm_eo; /* помера индекс да би се игнорисали почетни "вајт-спејс" карактери */ if (!regexec(®Symbol, input + *i, nmatches, a, 0)) { result->type = symbol; } else if (!regexec(®Number, input + *i, nmatches, a, 0)) { result->type = number; } else if (!regexec(®Parenthesis, input + *i, nmatches, a, 0)) { result->type = parenthesis; } else { result->type = undefined; result->lexeme = NULL; goto skipStringCopy; } result->lexeme = malloc((a[0].rm_eo + 1) * sizeof(char)); strncpy(result->lexeme, input + *i, a[0].rm_eo); result->lexeme[a[0].rm_eo] = '\0'; *i += a[0].rm_eo; regexec(®Space, input + *i, nmatches, a, 0); *i += a[0].rm_eo; /* игнорисање крајњих вајт-спејс карактера */ skipStringCopy: regfree(®Space); regfree(®Number); regfree(®Symbol); regfree(®Parenthesis); return result; }