그럴듯한 개발 블로그
반응형

하 드럽게 어렵다 증말로 스플릿으로 걍 자르면 될 줄 알았지
스터디 중에 파싱을 하기에 앞서 single quote, double quote(' , ")를 처리 중에 약간의 의견 충돌이 있었다.  세 명이서 돌아가며 서로의 방식을 설명하는데 체감 상 4바퀴 정도 빙빙 돌았다. 나도 주관이 강한 편인데 팀원들도 한 가락 하는 분들이라 의견 차이가 좁혀지지 않아, 각자 코드를 짜서 베스트 코드를 정하기로 했다. 한 시간 정도 짜다 보니 반정도 완성이 되었는데, 이건 안 되겠다 생각이 들었다... 중복 quote를 검사하려면 내 방식으로는 예외처리를 하기 힘들어 보였다. 그래도 일단 리뷰는 해야 하니 꾸역꾸역 환경변수 처리부를 제외하고 완성은 했는데, 다른 팀원에 비해 너무 가독성도 안 좋고, 로직도 불안정했다 ㅠㅜ.. 한 팀원의 방식이 너무 매력적이라 만장일치로 그 방식이 채택되었다. 그래도 아쉬우니까 업로드는 해 놔야지~~ 
+ 쿼츠 구조를 잘못 이해했다. 가장 크게 감싸고 있는 쿼츠끼리 한 쌍이 아니라 제일 먼저 만나는 두 쿼츠가 한쌍이다.

#include <stdbool.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <readline/readline.h>
#include <readline/history.h>
#include "libft/libft.h"

/**
 * 1. quote 해석 -> ", '
 * 2. $ 환경변수 해석
 * 3. 공백 분리
 * 4. 연산자 (파이프, 리다이렉션) 분리
 * 5. 연속된 argv 병합
 * 6. 공백 소각
 */

typedef struct s_data
{
	char			*original_str;
	int				single_quote;
	int				double_quote;
	struct s_node	*front;
}	t_data;

typedef struct s_node
{
	char			*token;
	struct s_node	*next;
}	t_node;

// |echo "aaa $a"|
// |echo aaa 123|

// |echo "aaa $a"|
// |echo |+|aaa $a| => |echo |+|aaa | + |123|
// |echo aaa 123|
// |echo|, | |, |aaa|, | |, |$a|
// |echo|, | |, |aaa|, | |, |123|
// |echo aaa 123|

t_node	*make_node(char *token)
{
	t_node	*res;

	res = (t_node*)malloc(sizeof(t_node));
	res->token = token;
	res->next = 0;
	return (res);
}

int	is_single_quo(char c)
{
	if (c == '\'')
		return (1);
	return (0);
}

int	is_double_quo(char c)
{
	if (c == '\"')
		return (1);
	return (0);
}

void	tokennize(t_data *data, char *input)
{
	t_node	*cur;

	data->front = make_node(0); // 노드 만들어서 front가리키게 해주기
	cur = data->front;
	int	i = -1, start_i = 0;
	while (input[++i])
	{
		if (is_single_quo(input[i]) && data->double_quote == 0)
		{
			cur->next = make_node(ft_substr(input, start_i, i - start_i));
			cur = cur->next;
			if (data->single_quote)
				data->single_quote -= 1;
			else
				data->single_quote += 1;
			start_i = i + 1;
		}
		else if (is_double_quo(input[i]) && data->single_quote == 0)
		{
			cur->next = make_node(ft_substr(input, start_i, i - start_i));
			cur = cur->next;
			if (data->double_quote)
				data->double_quote -= 1;
			else
				data->double_quote += 1;
			start_i = i + 1;
		}
	}
	cur->next = make_node(ft_substr(input, start_i, i - start_i));
	cur = cur->next; // 맨 처음 빈 노드를 삭제해준다 다른 좋은 방법이 있을 것 같은데... 너무 편법 느낌..
	cur = data->front;
	cur = cur->next;
	free(data->front);
	data->front = cur;
}

void	print_node(t_node *first)
{
	while (first)
	{
		printf("|%s|\n", first->token);
		first = first->next;
	}
}

int	main(void)
{
	char	*input;
	t_data	*data;

	input = readline("🥨 minishell$ ");
	data = (t_data*)malloc(sizeof(t_data));
	data->original_str = input;
	data->single_quote = 0;
	data->double_quote = 0;
	tokennize(data, input);
	print_node(data->front);
	free(input);
	return (0);
}

팀플 과제는 처음 해 보는데 스타일이 다 달라서 맞춰가는 중이다. 클러스터 아이맥 배치 때문에 짝코딩에 어려움이 있어 vscode의 liveshare로 진행해 봤는데 신기하고 유용했다. 공유 터미널은 딜레이가 생겨 불편하긴 했다.  그리고 황사 때문에 창문은 닫아놓고 에어컨은 안 틀어주는데 더 더워지면 테라스에 노트북 들고나가야겠다.. 스터디 파이팅

반응형

'<42seoul> > minishell' 카테고리의 다른 글

목걸이를 받지 못한 코드3  (0) 2023.04.13
목걸이를 받지 못한 코드2  (0) 2023.04.04
<< "'hi"|hi'  (2) 2023.03.30
profile

그럴듯한 개발 블로그

@donghyk2

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!