From 373e240e857974480732adb388cf46ef3eb2e59b Mon Sep 17 00:00:00 2001 From: gazhonsepaskwa Date: Sat, 8 Feb 2025 12:37:48 +0100 Subject: [PATCH] unstick update && syntax check --- srcs/parsing/parser.c | 2 - srcs/parsing/syntax.c | 79 ++++++++++++++++++--- srcs/parsing/tokenizer/token_and_pres.c | 6 +- srcs/parsing/tokenizer/tokenizer.c | 23 ++++++ srcs/parsing/tokenizer/tokenizer_utils.c | 30 ++++++-- srcs/parsing/tokenizer/unstick_node_utils.c | 4 +- 6 files changed, 124 insertions(+), 20 deletions(-) diff --git a/srcs/parsing/parser.c b/srcs/parsing/parser.c index efdb80a..bc29d78 100644 --- a/srcs/parsing/parser.c +++ b/srcs/parsing/parser.c @@ -46,8 +46,6 @@ t_ast_n *parser(char *input, t_msh *msh) lst = tokenize(input); if (!lst) return (NULL); - if (syntax_error(lst)) - return (NULL); if (DEBUG) { dio = drawio_init("ast.xml"); diff --git a/srcs/parsing/syntax.c b/srcs/parsing/syntax.c index f783a12..120ee2e 100644 --- a/srcs/parsing/syntax.c +++ b/srcs/parsing/syntax.c @@ -19,35 +19,96 @@ int only_operator(t_node *head) return (0); } -int syntax_err_mess(char *token) +int syntax_err_mess(char *token_base, int selected) { - ft_fprintf(2, "minishell : syntax error near unexpected token `%s'\n", - token); + char *token; + + token = ft_strdup(token_base); + if (selected == 0) + ft_fprintf(2, "minishell : syntax error : unexpected token `%s'\n", + token); + if (selected == 2) + ft_fprintf(2, "minishell : syntax error : unoppened token `%s'\n", + &token[1]); + token[1] = 0; + if (selected == 1) + ft_fprintf(2, "minishell : syntax error : unclosed token `%s'\n", + token); + free(token); return (1); } int unexpected_token(t_node *node) { - if (!ft_strncmp(node->val, "%", 1) || (!ft_strncmp(node->val, "&", 1) - && ft_strncmp(node->val, "&&", 2)) || !ft_strncmp(node->val, ";", 1) - || !ft_strncmp(node->val, "[", 1) || !ft_strncmp(node->val, "]", 1) - || !ft_strncmp(node->val, "{", 1) || !ft_strncmp(node->val, "}", 1)) + if ((!ft_strncmp(node->val, "&", 1) && ft_strncmp(node->val, "&&", 2)) + || !ft_strncmp(node->val, ";", 1) || !ft_strncmp(node->val, "[", 1) + || !ft_strncmp(node->val, "]", 1) || !ft_strncmp(node->val, "{", 1) + || !ft_strncmp(node->val, "}", 1)) return (1); return (0); } +int check_unclosed(char *c, t_node *node) +{ + t_node *cpy; + int count; + + cpy = node; + count = 0; + while (cpy) + { + if (!ft_strncmp(&c[0], cpy->val, 1)) + count++; + if (!ft_strncmp(&c[1], cpy->val, 1)) + count--; + cpy = cpy->next; + } + if (count > 0) + return (1); + if (count < 0) + return (2); + return (0); +} + +int check_unclosed_quote(char *c, t_node *node) +{ + t_node *cpy; + int count; + int len; + + cpy = node; + count = 0; + while (cpy) + { + len = ft_strlen(cpy->val); + if (len > 0 && cpy->val[0] == c[0]) + { + if (len == 1 || cpy->val[len - 1] != c[0]) + count++; + } + cpy = cpy->next; + } + return (count % 2); +} + int syntax_error(t_node *head) { t_node *cpy; if (only_operator(head)) - return (syntax_err_mess(head->val)); + return (syntax_err_mess(head->val, 0)); cpy = head; while (cpy) { if (unexpected_token(cpy)) - return (syntax_err_mess(cpy->val)); + return (syntax_err_mess(cpy->val, 0)); cpy = cpy->next; } + if (check_unclosed("()", head) != 0) + return (syntax_err_mess("()", check_unclosed("()", head))); + if (check_unclosed_quote("\"", head) != 0) + return (syntax_err_mess("\"\"", 1)); + if (check_unclosed_quote("'", head) != 0) + return (syntax_err_mess("'", 1)); return (0); } diff --git a/srcs/parsing/tokenizer/token_and_pres.c b/srcs/parsing/tokenizer/token_and_pres.c index fe1bf8d..5485077 100644 --- a/srcs/parsing/tokenizer/token_and_pres.c +++ b/srcs/parsing/tokenizer/token_and_pres.c @@ -39,9 +39,9 @@ t_token get_token(char *str) { t_token token; - if (!ft_strncmp(str, "&", 1) || !ft_strncmp(str, "|", 1) || !ft_strncmp(str, - "(", 1) || !ft_strncmp(str, ")", 1) || !ft_strncmp(str, "<", 1) - || !ft_strncmp(str, ">", 1)) + if (!ft_strncmp(str, "&", 1) || !ft_strncmp(str, "|", 1) + || !ft_strncmp(str, "(", 1) || !ft_strncmp(str, ")", 1) + || !ft_strncmp(str, "<", 1) || !ft_strncmp(str, ">", 1)) token = OPERATOR; else token = WORD; diff --git a/srcs/parsing/tokenizer/tokenizer.c b/srcs/parsing/tokenizer/tokenizer.c index d6c587d..6cd4f5b 100644 --- a/srcs/parsing/tokenizer/tokenizer.c +++ b/srcs/parsing/tokenizer/tokenizer.c @@ -103,6 +103,23 @@ static int stick_quote_node(t_node *head, char q) return (1); } +void debug_token_list(t_node* lst, char *msg) +{ + t_node *cpy; + + cpy = lst; + if (DEBUG) + { + ft_debug("========================={%s}\n", msg); + while (cpy) + { + ft_debug("|%s|\n", cpy->val); + cpy = cpy->next; + } + ft_debug("=========================\n\n"); + } +} + t_node *tokenize(char *str) { t_node *head; @@ -110,12 +127,18 @@ t_node *tokenize(char *str) head = tokenize_base(str); if (!head) return (NULL); + // debug_token_list(head, "tokenize_base"); if (!trim_nodes(head)) return (NULL); + // debug_token_list(head, "trim_nodes"); if (!unstick_nodes(head)) return (NULL); + // debug_token_list(head, "unstick_nodes"); stick_quote_node(head, 39); stick_quote_node(head, '"'); + debug_token_list(head, "tokenizer"); set_token(head); + if (syntax_error(head)) + return (NULL); return (head); } diff --git a/srcs/parsing/tokenizer/tokenizer_utils.c b/srcs/parsing/tokenizer/tokenizer_utils.c index 52b740a..786bd56 100644 --- a/srcs/parsing/tokenizer/tokenizer_utils.c +++ b/srcs/parsing/tokenizer/tokenizer_utils.c @@ -15,29 +15,49 @@ int is_meta(char c) { if (c == '&' || c == '|' || c == '<' || c == '>' || c == '(' || c == ')' - || c == '"' || c == 39) + || c == '"' || c == 39 || c == ';' || c == '{' || c == '}' || c == '[' + || c == ']') return (1); return (0); } +int unic(int *meta) +{ + int i; + int ref_meta; + + i = -1; + ref_meta = meta[0]; + while (meta[++i] != -1) + if (meta[i] != ref_meta) + return (0); + return (1); +} + int is_sticked(char *val) { int i; - int meta; + int meta[100]; + int meta_it; int unmeta; i = 0; - meta = 0; + meta_it = 0; + meta[0] = -1; unmeta = 0; while (val[i]) { if (is_meta(val[i])) - meta = 1; + { + meta[meta_it] = val[i]; + meta_it++; + } if (!is_meta(val[i])) unmeta = 1; i++; } - if (meta && unmeta) + meta[meta_it] = -1; + if ((meta[0] != -1 && unmeta) || !unic(meta)) return (1); return (0); } diff --git a/srcs/parsing/tokenizer/unstick_node_utils.c b/srcs/parsing/tokenizer/unstick_node_utils.c index 852ef60..a7668c5 100644 --- a/srcs/parsing/tokenizer/unstick_node_utils.c +++ b/srcs/parsing/tokenizer/unstick_node_utils.c @@ -17,9 +17,11 @@ char *copy_meta_xor(char *val, int *copied, int rev) int i; int j; char *out; + char ref; i = 0; - while (is_meta(val[i]) ^ rev) + ref = val[0]; + while ((is_meta(val[i]) && val[i] == ref) ^ rev) i++; *copied = i; out = malloc(i + 1);