Skip to content

Commit

Permalink
fix<double_quotes>: fix and add double quote and variable assignment
Browse files Browse the repository at this point in the history
This commit should add the double quote handling and variable assignment handling in lexer
  • Loading branch information
ErwannLesech committed Jan 15, 2024
1 parent daae1d4 commit 646c74c
Show file tree
Hide file tree
Showing 8 changed files with 324 additions and 30 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@
## Installation

```sh
git clone <path>
cd <path>
make
git clone [email protected]:ErwannLesech/42-Sh.git
cd 42-Sh
./42-install.sh
cd src/
```

## Usage
Expand Down
2 changes: 1 addition & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ bin_PROGRAMS = 42sh

42sh_CPPFLAGS = -I%D%

42sh_CFLAGS = -std=c99 -Werror -Wall -Wextra -Wvla -pedantic -fsanitize=address -g
42sh_CFLAGS = -std=c99 -Werror -Wall -Wextra -Wvla -pedantic

42sh_LDADD = lexer/liblexer.a \
ast/libast.a \
Expand Down
44 changes: 36 additions & 8 deletions src/lexer/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ struct lex_match lex_match[] = {
{ "&&", TOKEN_AND }, { "||", TOKEN_OR }, { "|", TOKEN_PIPE },
{ "!", TOKEN_NEGATE }, { "<", TOKEN_REDIR }, { ">", TOKEN_REDIR },
{ ">>", TOKEN_REDIR }, { "<&", TOKEN_REDIR }, { ">&", TOKEN_REDIR },
{ ">|", TOKEN_REDIR }, { "<>", TOKEN_REDIR },

{ "$*", TOKEN_VARIABLE }
{ ">|", TOKEN_REDIR }, { "<>", TOKEN_REDIR }
};

struct lexer *lexer_new(const char *input)
Expand Down Expand Up @@ -105,16 +103,37 @@ char *get_word(struct lexer *lexer, bool *is_diactivated)
&& lexer->data[lexer->index] != '|'
&& lexer->data[lexer->index] != '&')
{
if (lexer->data[lexer->index] == '=' && word_index > 0 && lexer->curr_tok.type != TOKEN_DOUBLE_QUOTE)
{
printf("word1: %s\n", word);
lexer->curr_tok.type = TOKEN_WORD_ASSIGNMENT;
lexer->index += 1;
break;
}
word = realloc(word, sizeof(char) * (word_index + 1));
word[word_index] = lexer->data[lexer->index];
++word_index;
++lexer->index;
if (lexer->data[lexer->index - 1] == '\\')
if (lexer->data[lexer->index - 1] == '\"'
|| lexer->curr_tok.type == TOKEN_DOUBLE_QUOTE)
{
if (!handle_backslash(lexer, is_diactivated, word, word_index))
if (lexer->data[lexer->index - 1] == '\"')
{
word_index -= 1;
lexer->curr_tok.type = TOKEN_DOUBLE_QUOTE;
}
word = handle_double_quote(lexer, is_diactivated, word,
&word_index);
if (!word)
{
return word;
return NULL;
}
word[word_index] = '\0';
return word;
}
else if (lexer->data[lexer->index - 1] == '\\')
{
handle_backslash(lexer, is_diactivated, word, word_index);
}
else if (lexer->data[lexer->index - 1] == '\'')
{
Expand Down Expand Up @@ -161,6 +180,15 @@ struct token parse_input_for_tok(struct lexer *lexer)
return token;
}

if (lexer->curr_tok.type == TOKEN_WORD_ASSIGNMENT)
{
token.type = TOKEN_WORD_ASSIGNMENT;
token.data = word;
lexer->curr_tok.type = TOKEN_EOL;
printf("word: %s\n", word);
return token;
}

for (unsigned i = 0; i < sizeof(lex_match) / sizeof(*lex_match); ++i)
{
if (fnmatch(lex_match[i].str, word, 0) == 0 && !is_diactivated)
Expand All @@ -170,7 +198,7 @@ struct token parse_input_for_tok(struct lexer *lexer)
return token;
}
}

token.type = TOKEN_WORD;
token.data = word;
return token;
Expand Down Expand Up @@ -201,7 +229,7 @@ struct token lexer_pop(struct lexer *lexer)
return token;
}
struct token token = parse_input_for_tok(lexer);
if (token.type != TOKEN_EOF)
if (token.type == TOKEN_EOF)
{
lexer->curr_tok = token;
}
Expand Down
10 changes: 9 additions & 1 deletion src/lexer/lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ struct token lexer_pop(struct lexer *lexer);
*
* \return false if it's the end of the string, true otherwise.
*/
bool handle_backslash(struct lexer *lexer, bool *is_diactivated, char *word,
void handle_backslash(struct lexer *lexer, bool *is_diactivated, char *word,
unsigned word_index);

/**
Expand All @@ -91,6 +91,14 @@ bool handle_backslash(struct lexer *lexer, bool *is_diactivated, char *word,
char *handle_simple_quote(struct lexer *lexer, bool *is_diactivated, char *word,
unsigned *word_index);

/**
* \brief Handle the double quote character.
* \param lexer The lexer.
* \return The next word.
*/
char *handle_double_quote(struct lexer *lexer, bool *is_diactivated, char *word,
unsigned *word_index);

/**
* \brief Handle the comment character.
*
Expand Down
137 changes: 132 additions & 5 deletions src/lexer/lexer_utils.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#include <fnmatch.h>
#include <stdlib.h>
#include <stdio.h>

#include "lexer.h"

bool handle_backslash(struct lexer *lexer, bool *is_diactivated, char *word,
void handle_backslash(struct lexer *lexer, bool *is_diactivated, char *word,
unsigned word_index)
{
*is_diactivated = true;
Expand All @@ -14,10 +16,7 @@ bool handle_backslash(struct lexer *lexer, bool *is_diactivated, char *word,
else
{
word[word_index - 1] = '\0';
return false;
}

return true;
}

char *handle_simple_quote(struct lexer *lexer, bool *is_diactivated, char *word,
Expand All @@ -42,6 +41,134 @@ char *handle_simple_quote(struct lexer *lexer, bool *is_diactivated, char *word,
return word;
}

/**
* \brief Check if the given word is a variable name.
* \param lexer The lexer.
* \param word The word to check.
*/
char *check_variable_name(struct lexer *lexer, char *word, unsigned *word_index)
{
if (lexer->data[lexer->index] == '?' || lexer->data[lexer->index] == '*'
|| lexer->data[lexer->index] == '@' || lexer->data[lexer->index] == '#'
|| lexer->data[lexer->index] == '$')
{
word = realloc(word, sizeof(char) * (*word_index + 1));
word[*word_index] = lexer->data[lexer->index];
*word_index += 1;
lexer->index += 1;
return word;
}
else if (lexer->data[lexer->index] >= '0'
&& lexer->data[lexer->index] <= '9')
{
while (lexer->data[lexer->index] >= '0'
&& lexer->data[lexer->index] <= '9')
{
word = realloc(word, sizeof(char) * (*word_index + 1));
word[*word_index] = lexer->data[lexer->index];
*word_index += 1;
lexer->index += 1;
}
return word;
}
else if (lexer->data[lexer->index] == '_'
|| lexer->data[lexer->index] == '-'
|| (lexer->data[lexer->index] >= 'a'
&& lexer->data[lexer->index] <= 'z')
|| (lexer->data[lexer->index] >= 'A'
&& lexer->data[lexer->index] <= 'Z'))
{
word = realloc(word, sizeof(char) * (*word_index + 1));
word[*word_index] = lexer->data[lexer->index];
*word_index += 1;
lexer->index += 1;
}
else
{
return NULL;
}

while (lexer->data[lexer->index] != ' ' && lexer->data[lexer->index] != '\t'
&& lexer->data[lexer->index] != '\n'
&& lexer->data[lexer->index] != '\0')
{
if (lexer->data[lexer->index] == '_' || lexer->data[lexer->index] == '-'
|| (lexer->data[lexer->index] >= 'a'
&& lexer->data[lexer->index] <= 'z')
|| (lexer->data[lexer->index] >= 'A'
&& lexer->data[lexer->index] <= 'Z')
|| (lexer->data[lexer->index] >= '0'
&& lexer->data[lexer->index] <= '9'))
{
word = realloc(word, sizeof(char) * (*word_index + 1));
word[*word_index] = lexer->data[lexer->index];
*word_index += 1;
lexer->index += 1;
}
else
{
return word;
}
}

return word;
}

char *handle_double_quote(struct lexer *lexer, bool *is_diactivated, char *word,
unsigned *word_index)
{
*is_diactivated = true;
if (lexer->data[lexer->index] == '$')
{
word = realloc(word, sizeof(char) * (*word_index + 1));
word[*word_index] = lexer->data[lexer->index];
*word_index += 1;
lexer->index += 1;
char *word_tmp = check_variable_name(lexer, word, word_index);
if (word_tmp != NULL)
{
word = word_tmp;
}
else
{
return word;
}
}
while (lexer->data[lexer->index] != '\"' && lexer->data[lexer->index] != '$')
{
if (lexer->data[lexer->index] == '\0')
{
free(word);
word = NULL;
return NULL;
}
else if (lexer->data[lexer->index] == '\\')
{
lexer->index += 1;
if (lexer->data[lexer->index] == '\"'
|| lexer->data[lexer->index] == '$'
|| lexer->data[lexer->index] == '\\'
|| lexer->data[lexer->index] == '\n')
{
word = realloc(word, sizeof(char) * (*word_index + 1));
word[*word_index] = lexer->data[lexer->index];
*word_index += 1;
lexer->index += 1;
}
}
word = realloc(word, sizeof(char) * (*word_index + 1));
word[*word_index] = lexer->data[lexer->index];
*word_index += 1;
lexer->index += 1;
}
if (lexer->data[lexer->index] == '\"')
{
lexer->curr_tok.type = TOKEN_EOL;
++lexer->index;
}
return word;
}

char *handle_comment(struct lexer *lexer, char *word, unsigned *word_index)
{
// Skip the comment
Expand Down Expand Up @@ -90,4 +217,4 @@ char *handle_redir(struct lexer *lexer, unsigned *word_index)
++lexer->index;
}
return redir;
}
}
Loading

0 comments on commit 646c74c

Please sign in to comment.