static size_t readname (LexState *LS, char ch) { size_t l = 0; checkbuffer(LS, l); if (ch != 0) { checkbuffer(LS, l); save(LS, ch, l); } do { checkbuffer(LS, l); save_and_next(LS, l); } while (lex_isalnum(LS->current) || LS->current == '_'); save(LS, '\0', l); return l-1; }
/** * Do lexical analysis of buffer in 'str'. * * And start do add tokens after 'prev' * * Returns pointer to last token, or NULL if an error occured. * If an error occured 'ei' will be filled with data */ token_t * glw_view_lexer(glw_root_t *gr, const char *src, errorinfo_t *ei, rstr_t *f, token_t *prev) { const char *start; int line = 1; token_t *t; while(*src != 0) { if(*src == '\n') { /* newline */ /* TODO: DOS CR support ? */ src++; line++; continue; } if(*src <= 32) { /* whitespace */ src++; continue; } if(src[0] == 'v' && src[1] == 'o' && src[2] == 'i' && src[3] == 'd') { prev = lexer_add_token_simple(gr, prev, f, line, TOKEN_VOID); src+=4; continue; } if(src[0] == 't' && src[1] == 'r' && src[2] == 'u' && src[3] == 'e') { prev = lexer_add_token_simple(gr, prev, f, line, TOKEN_INT); src+=4; prev->t_int = 1; continue; } if(src[0] == 'f' && src[1] == 'a' && src[2] == 'l' && src[3] == 's' && src[4] == 'e') { prev = lexer_add_token_simple(gr, prev, f, line, TOKEN_INT); src+=5; prev->t_int = 0; continue; } if(*src == '/' && src[1] == '/') { // C++ style comment src += 2; while(*src != '\n') src++; src++; line++; continue; } if(*src == '/' && src[1] == '*') { /* A normal C-comment */ src += 2; while(*src != '/' || src[-1] != '*') { if(*src == '\n') line++; src++; } src++; continue; } if(src[0] == '&' && src[1] == '&') { prev = lexer_add_token_simple(gr, prev, f, line, TOKEN_BOOLEAN_AND); src+=2; continue; } if(src[0] == '?' && src[1] == '=') { prev = lexer_add_token_simple(gr, prev, f, line, TOKEN_COND_ASSIGNMENT); src+=2; continue; } if(src[0] == '<' && src[1] == '-') { prev = lexer_add_token_simple(gr, prev, f, line, TOKEN_LINK_ASSIGNMENT); src+=2; continue; } if(src[0] == ':' && src[1] == '=') { prev = lexer_add_token_simple(gr, prev, f, line, TOKEN_REF_ASSIGNMENT); src+=2; continue; } if(src[0] == '_' && src[1] == '=' && src[2] == '_') { prev = lexer_add_token_simple(gr, prev, f, line, TOKEN_DEBUG_ASSIGNMENT); src+=3; continue; } if(src[0] == '|' && src[1] == '|') { prev = lexer_add_token_simple(gr, prev, f, line, TOKEN_BOOLEAN_OR); src+=2; continue; } if(src[0] == '^' && src[1] == '^') { prev = lexer_add_token_simple(gr, prev, f, line, TOKEN_BOOLEAN_XOR); src+=2; continue; } if(src[0] == '=' && src[1] == '=') { prev = lexer_add_token_simple(gr, prev, f, line, TOKEN_EQ); src+=2; continue; } if(src[0] == '!' && src[1] == '=') { prev = lexer_add_token_simple(gr, prev, f, line, TOKEN_NEQ); src+=2; continue; } if(src[0] == '?' && src[1] == '?') { prev = lexer_add_token_simple(gr, prev, f, line, TOKEN_NULL_COALESCE); src+=2; continue; } if(!(src[0] == '-' && lex_isdigit(src[1]))) { if((t = lexer_single_char(gr, prev, f, line, *src)) != NULL) { src++; prev = t; continue; } } start = src; if(*src == '"' || *src == '\'') { /* A quoted string " ... " */ char stop = *src; src++; start++; while((*src != stop || (src[-1] == '\\' && src[-2] != '\\')) && *src != 0) { if(*src == '\n') line++; src++; } if(*src != stop) { snprintf(ei->error, sizeof(ei->error), "Unterminated quote"); snprintf(ei->file, sizeof(ei->file), "%s", rstr_get(f)); ei->line = line; return NULL; } prev = lexer_add_token_string(gr, prev, f, line, start, src, TOKEN_RSTRING); if(stop == '\'') prev->t_rstrtype = PROP_STR_RICH; src++; continue; } if(lex_isalpha(*src)) { /* Alphanumeric string */ while(lex_isalnum(*src)) src++; prev = lexer_add_token_string(gr, prev, f, line, start, src, TOKEN_IDENTIFIER); continue; } if(lex_isdigit(*src)) { /* Integer */ while(lex_isdigit(*src)) src++; if(*src == '.') { src++; /* , or a float */ while(lex_isdigit(*src)) src++; } if(*src == 'f') /* we support having the 'f' postfix around too */ src++; prev = lexer_add_token_float(gr, prev, f, line, start, src); continue; } snprintf(ei->error, sizeof(ei->error), "Invalid char '%c'", *src > 31 ? *src : ' '); snprintf(ei->file, sizeof(ei->file), "%s", rstr_get(f)); ei->line = line; return NULL; } return prev; }