diff options
| author | Ákos Kőrösi <korakos99@gmail.com> | 2026-05-12 12:57:20 +0200 |
|---|---|---|
| committer | Ákos Kőrösi <korakos99@gmail.com> | 2026-05-12 12:57:20 +0200 |
| commit | 3297384ec22c4931dc86b2429c8afe25b436682d (patch) | |
| tree | eeff6e612c84a8cfc0b7f32484a0f4e2ee1da91f | |
| parent | a668be570b3b1b1d4c8a7e85159eece4080217c1 (diff) | |
add parsing codes and lexing renames
- outline more sketch code for parsing
- rename Region
| -rw-r--r-- | lex.c | 42 | ||||
| -rw-r--r-- | lex.h | 16 | ||||
| -rw-r--r-- | parse.c | 45 |
3 files changed, 68 insertions, 35 deletions
@@ -26,7 +26,7 @@ String collect_identifier(RawLine* line) { -TokenVec lex_level(RawLine* line, char until, ExpansionRegionVec* reg_arena); +TokenVec lex_level(RawLine* line, char until, RegionVec* reg_arena); void expect_char(RawLine* line, char expected) { @@ -38,7 +38,7 @@ void expect_char(RawLine* line, char expected) { } -MaybeChunk lex_expansion_chunk(RawLine* line, ExpansionRegionVec* reg_arena, QuotationMode qmode) { +MaybeChunk lex_expansion_chunk(RawLine* line, RegionVec* reg_arena, QuotationMode qmode) { line->pos++; // Consume $ if (line->str[line->pos] == '(') { line->pos++; @@ -50,11 +50,11 @@ MaybeChunk lex_expansion_chunk(RawLine* line, ExpansionRegionVec* reg_arena, Quo TokenVec inner_toks = lex_level(line, ')', reg_arena); expect_char(line, ')'); expect_char(line, ')'); - push_to_ExpansionRegionVec( + push_to_RegionVec( reg_arena, - (ExpansionRegion){.mode = ARITHM, .tokens = inner_toks} + (Region){.mode = ARITHM, .tokens = inner_toks} ); - ExpansionRegion* reg_ptr = ®_arena->items[reg_arena->count]; // TODO: maybe have push() return a pointer [in the macro] + Region* reg_ptr = ®_arena->items[reg_arena->count]; // TODO: maybe have push() return a pointer [in the macro] return (MaybeChunk){ .some = true, .value = (Chunk){ @@ -66,11 +66,11 @@ MaybeChunk lex_expansion_chunk(RawLine* line, ExpansionRegionVec* reg_arena, Quo } else { TokenVec inner_toks = lex_level(line, ')', reg_arena); expect_char(line, ')'); - push_to_ExpansionRegionVec( + push_to_RegionVec( reg_arena, - (ExpansionRegion){.mode = CMD_SUB, .tokens = inner_toks} + (Region){.mode = CMD_SUB, .tokens = inner_toks} ); - ExpansionRegion* reg_ptr = ®_arena->items[reg_arena->count]; + Region* reg_ptr = ®_arena->items[reg_arena->count]; return (MaybeChunk) { .some = true, .value = (Chunk){ @@ -97,7 +97,7 @@ MaybeChunk lex_expansion_chunk(RawLine* line, ExpansionRegionVec* reg_arena, Quo } -void lex_double_quoted_section(RawLine* line, ChunkVec* coll, ExpansionRegionVec* reg_arena) { +void lex_double_quoted_section(RawLine* line, Word* coll, RegionVec* reg_arena) { line->pos++; String accum = make_String(256); while (line->str[line->pos] != '\"') { @@ -117,20 +117,20 @@ void lex_double_quoted_section(RawLine* line, ChunkVec* coll, ExpansionRegionVec if (exp_chunk.some) { if (accum.count > 0) { - push_to_ChunkVec(coll, (Chunk){ + push_to_Word(coll, (Chunk){ .qmode = DOUBLE_Q, .kind = LITERAL, .as.literal_str = inner(accum) }); accum = make_String(256); } - push_to_ChunkVec(coll, exp_chunk.value); + push_to_Word(coll, exp_chunk.value); exp_chunk.some = false; } } line->pos++; if (accum.count > 0) { - push_to_ChunkVec(coll, (Chunk){ + push_to_Word(coll, (Chunk){ .qmode = DOUBLE_Q, .kind = LITERAL, .as.literal_str = inner(accum) @@ -139,7 +139,7 @@ void lex_double_quoted_section(RawLine* line, ChunkVec* coll, ExpansionRegionVec } -Chunk next_word_unquoted(RawLine* line, ExpansionRegionVec* reg_arena) { +Chunk next_word_unquoted(RawLine* line, RegionVec* reg_arena) { String buf = make_String(256); for (char c; (c=line->str[line->pos], c != '$' && c != '\0' && c != ' '); line->pos++) { push_to_String(&buf, c); @@ -165,11 +165,11 @@ Chunk collect_single_quoted_section(RawLine* line) { -TokenVec lex_level(RawLine* line, char until, ExpansionRegionVec* reg_arena) { +TokenVec lex_level(RawLine* line, char until, RegionVec* reg_arena) { printf("\n\n==== START LEVEL ===\n\n"); TokenVec tokens = make_TokenVec(256); - ChunkVec curr_chunks = make_ChunkVec(256); + Word curr_chunks = make_Word(256); String word_buf = make_String(256); while (line->str[line->pos] != until) { @@ -177,7 +177,7 @@ TokenVec lex_level(RawLine* line, char until, ExpansionRegionVec* reg_arena) { if (line->str[line->pos] == ' ') { if (word_buf.count > 0) { - push_to_ChunkVec( + push_to_Word( &curr_chunks, (Chunk){.qmode = UN_Q, .kind = LITERAL, .as.literal_str = inner(word_buf)} ); @@ -185,7 +185,7 @@ TokenVec lex_level(RawLine* line, char until, ExpansionRegionVec* reg_arena) { } if (curr_chunks.count > 0) { push_to_TokenVec(&tokens, (Token){.kind = TOK_WORD, .as.word = curr_chunks}); - curr_chunks = make_ChunkVec(256); + curr_chunks = make_Word(256); } while (line->str[line->pos] == ' ') line->pos++; @@ -193,7 +193,7 @@ TokenVec lex_level(RawLine* line, char until, ExpansionRegionVec* reg_arena) { switch (line->str[line->pos]) { case '\'': - push_to_ChunkVec(&curr_chunks, collect_single_quoted_section(line)); + push_to_Word(&curr_chunks, collect_single_quoted_section(line)); break; case '\"': lex_double_quoted_section(line, &curr_chunks, reg_arena); @@ -202,7 +202,7 @@ TokenVec lex_level(RawLine* line, char until, ExpansionRegionVec* reg_arena) { line->pos++; MaybeChunk mchunk = lex_expansion_chunk(line, reg_arena, UN_Q); if (mchunk.some) { - push_to_ChunkVec(&curr_chunks, mchunk.value); + push_to_Word(&curr_chunks, mchunk.value); } else { push_to_String(&word_buf, '$'); } @@ -213,7 +213,7 @@ TokenVec lex_level(RawLine* line, char until, ExpansionRegionVec* reg_arena) { } if (word_buf.count > 0) { - push_to_ChunkVec( + push_to_Word( &curr_chunks, (Chunk){.qmode = UN_Q, .kind = LITERAL, .as.literal_str = inner(word_buf)} ); @@ -228,7 +228,7 @@ TokenVec lex_level(RawLine* line, char until, ExpansionRegionVec* reg_arena) { LexResult lex(char* input) { RawLine line = {.str = input, .pos = 0}; - ExpansionRegionVec reg_arena = make_ExpansionRegionVec(256); + RegionVec reg_arena = make_RegionVec(256); TokenVec toks = lex_level(&line, '\0', ®_arena); return (LexResult){.top_tokens = toks, .reg_arena = reg_arena}; } @@ -4,7 +4,7 @@ #include "typeutils.h" -typedef struct ExpansionRegion ExpansionRegion; +typedef struct Region Region; typedef enum { @@ -24,13 +24,15 @@ typedef struct { QuotationMode qmode; union { char* literal_str; - ExpansionRegion* reg_ptr; + Region* reg_ptr; char* varname; } as; } Chunk; -DECLARE_VEC(Chunk, ChunkVec) +DECLARE_VEC(Chunk, Word) + +DECLARE_VEC(Word, WordVec) typedef enum { TOK_WORD, @@ -52,7 +54,7 @@ typedef struct { TokenKind kind; union { - ChunkVec word; + Word word; SpecialToken spec; } as; } Token; @@ -67,19 +69,19 @@ typedef enum { ARITHM, } RegionMode; -struct ExpansionRegion { +struct Region { RegionMode mode; TokenVec tokens; }; DECLARE_MAYBE(Chunk); -DECLARE_VEC(ExpansionRegion, ExpansionRegionVec) +DECLARE_VEC(Region, RegionVec) typedef struct { TokenVec top_tokens; - ExpansionRegionVec reg_arena; + RegionVec reg_arena; } LexResult; @@ -1,3 +1,5 @@ +#include <stdlib.h> + #include "typeutils.h" #include "lex.h" @@ -5,13 +7,15 @@ DECLARE_VEC(char*, StrVec) typedef struct { - TokenVec tokens; + Token* ptr; + size_t len; size_t pos; } TokStream; typedef enum { STDIN_REDIR, - STDOUT_REDIT, + STDOUT_REDIR_TRUNC, + STDOUT_REDIR_APPEND, } RedirKind; @@ -19,14 +23,14 @@ typedef struct { RedirKind kind; union { - char* std_redir_filename; + Word std_redir_filename; } as; } Redirect; DECLARE_VEC(Redirect, RedirectVec) typedef struct { - StrVec args; + WordVec args; RedirectVec redirects; // TODO: prefix variable settings } Command; @@ -48,21 +52,48 @@ typedef struct { DECLARE_VEC(PipelineElement, Pipeline) + Command parse_command(TokStream* toks) { - StrVec args = make_StrVec(256); + WordVec args = make_WordVec(256); RedirectVec redirects = make_RedirectVec(256); for ( Token curr_tok; - (curr_tok = toks->tokens.items[toks->pos], !(curr_tok.kind == TOK_SPECIAL && (curr_tok.as.spec == PIPE && curr_tok.as.spec == EOL))); + (curr_tok = toks->ptr[toks->pos], !(curr_tok.kind == TOK_SPECIAL && (curr_tok.as.spec == PIPE && curr_tok.as.spec == EOL))); toks->pos++ ) { if (curr_tok.kind == TOK_SPECIAL) { + Token tok; + switch (curr_tok.as.spec) { + case WRITE_REDIR_TRUNC: + toks->pos++; + tok = toks->ptr[toks->pos]; + if(tok.kind != TOK_WORD) exit(1); + push_to_RedirectVec(&redirects, (Redirect){.kind = STDOUT_REDIR_TRUNC, .as.std_redir_filename = tok.as.word}); + break; + case WRITE_REDIR_APPEND: + toks->pos++; + tok = toks->ptr[toks->pos]; + if(tok.kind != TOK_WORD) exit(1); + push_to_RedirectVec(&redirects, (Redirect){.kind = STDOUT_REDIR_APPEND, .as.std_redir_filename = tok.as.word}); + break; + case READ_REDIR: + toks->pos++; + tok = toks->ptr[toks->pos]; + if(tok.kind != TOK_WORD) exit(1); + push_to_RedirectVec(&redirects, (Redirect){.kind = STDOUT_REDIR_APPEND, .as.std_redir_filename = tok.as.word}); + break; + default: + exit(69); + } + } else if (curr_tok.kind == TOK_WORD){ + push_to_WordVec(&args, curr_tok.as.word); } } + return (Command){.args = args, .redirects = redirects}; } Pipeline parse_tokstream(TokenVec toks) { - TokStream tokstream = {.tokens = toks, .pos = 0}; + TokStream tokstream = {.ptr = toks.items, .len = toks.count, .pos = 0}; Pipeline result = make_Pipeline(256); } |
