#include "lexer.h" #include #include #include #include #include #include void free_tokens(struct TOKEN *token) { for (; token;) { struct TOKEN *old = token; token = token->next; free(old); } } int is_special_char(char c) { if (!isprint(c)) return 1; if (isspace(c)) return 1; if (isalnum(c)) return 0; return !(('>' != c && '|' != c && '&' != c)); } int parse_chars(struct sv *code_ptr, struct TOKEN *cur) { struct sv code = *code_ptr; if (is_special_char(sv_peek(code))) return 0; cur->type = TOKEN_CHARS; cur->string_rep = sv_split_function(code, &code, is_special_char); *code_ptr = code; return 1; } // Operands such as: &, &&, |, || etc // Is operands the right word? int parse_operand(struct sv *code_ptr, struct TOKEN *cur) { struct sv code = *code_ptr; #define TRY_PARSE_STRING(_s, _token) \ if (sv_partial_eq(code, C_TO_SV(_s))) { \ cur->type = TOKEN_AND; \ cur->string_rep = sv_take(code, &code, strlen(_s)); \ goto complete_return; \ } TRY_PARSE_STRING("&&", TOKEN_AND); TRY_PARSE_STRING("||", TOKEN_NOT); TRY_PARSE_STRING(">>", TOKEN_STREAM_APPEND); TRY_PARSE_STRING(">", TOKEN_STREAM); TRY_PARSE_STRING("|", TOKEN_PIPE); // TODO: & // Failed to parse return 0; complete_return: *code_ptr = code; return 1; } void skip_whitespace(struct sv *s) { *s = sv_skip_chars(*s, " \t\n\r"); } struct TOKEN *lex(struct sv code) { struct TOKEN *head = NULL; struct TOKEN *prev = NULL; for (; !sv_isempty(code);) { skip_whitespace(&code); if (sv_isempty(code)) { break; } struct TOKEN *cur = malloc(sizeof(struct TOKEN)); cur->next = NULL; if (prev) prev->next = cur; if (parse_chars(&code, cur)) { } else if (parse_operand(&code, cur)) { } else { free(cur); printf("at: %s\n", code); assert(0 && "Unknown token"); } if (!head) head = cur; prev = cur; } return head; }