From b38a1cba97c9065e8d1801b6d3fcbcbcada36e68 Mon Sep 17 00:00:00 2001 From: Maieul BOYER Date: Mon, 25 Mar 2024 15:15:49 +0100 Subject: [PATCH] Added: Rust parser WIP --- rust/parser/Cargo.lock | 7 +++ rust/parser/Cargo.toml | 8 +++ rust/parser/src/main.rs | 136 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+) create mode 100644 rust/parser/Cargo.lock create mode 100644 rust/parser/Cargo.toml create mode 100644 rust/parser/src/main.rs diff --git a/rust/parser/Cargo.lock b/rust/parser/Cargo.lock new file mode 100644 index 00000000..41a46c2a --- /dev/null +++ b/rust/parser/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "parser-rs" +version = "0.1.0" diff --git a/rust/parser/Cargo.toml b/rust/parser/Cargo.toml new file mode 100644 index 00000000..9dffbf9d --- /dev/null +++ b/rust/parser/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "parser-rs" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/rust/parser/src/main.rs b/rust/parser/src/main.rs new file mode 100644 index 00000000..caa4f421 --- /dev/null +++ b/rust/parser/src/main.rs @@ -0,0 +1,136 @@ +#![allow(dead_code)] +use std::convert::Infallible as Never; + +type WORD = String; +type Rule2 = String; +type Rule3 = String; + +struct SourceFile { + cmds: Vec, +} + +struct CompleteCommands { + // each Pipeline Must have a Separator, but the + // last Pipeline is optional + list: Vec<(Pipeline, Option)>, +} + +enum SeparatorOp { + Semi, /* ; */ + Fork, /* & */ +} + +struct Pipeline { + bang: bool, // placed before the seqence + kind: Option, // placed after the seqence + seq: Vec, // each cmd are piped into the next +} + +enum PipelineKind { + Or, /* || */ + And, /* && */ +} + +enum Commands { + Simple(SimpleCommand), + Compound(Never), + FuncDef(Never), +} + +struct SimpleCommand { + prefix: Vec, + cmd: Vec, // First is rule 7a, then 7b + suffix: Vec, +} + +enum CmdPrefix { + IoRedirect(IoRedirect), + Assigment(Assigment), +} + +enum CmdSuffix { + IoRedirect(IoRedirect), + Word(WORD), +} + +struct IoRedirect { + io_file: Option, + io_kind: IoKind, +} + +enum IoKind { + IoFile(IoFile), + IoHere(IoHere), +} + +enum IoFile { + Less { filename: Rule2 }, /* < */ + Greater { filename: Rule2 }, /* > */ + LessAnd { filename: Rule2 }, /* <& */ + GreaterAnd { filename: Rule2 }, /* >& */ + DoubleGreater { filename: Rule2 }, /* >> */ + LessGreater { filename: Rule2 }, /* <> */ + Clobber { filename: Rule2 }, /* >| */ +} +enum IoHere { + Dless { here_end: Rule3 }, /* << */ + DlessDash { here_end: Rule3 }, /* <<- */ +} + +// Rule 7 +struct Assigment { + key: WORD, + value: WORD, +} + +#[derive(Default)] +struct TokenizerState<'input> { + current_pos: usize, + input: &'input str, + remaining: &'input str, +} + +enum Token<'input> { + Thingy { val: &'input str, start_pos: usize }, + SingleQuote { val: &'input str, start_pos: usize }, +} + +fn tokenizer<'state, 'input: 'state>( + state: &'state mut TokenizerState<'input>, +) -> impl Iterator> + 'state { + state.current_pos = 0; + std::iter::from_fn(move || { + let state = &mut *state; + let mut chars = state.remaining.chars().peekable(); + let mut len = 1; + + let Some(chr) = chars.next() else { + return None; + }; + match chr { + '\'' => { + while chars.peek().copied() != Some('\'') { + len += 1; + chars.next(); + } + let old_current = state.current_pos; + state.current_pos += len; + let old_remaining = state.remaining; + state.remaining = &state.remaining[len..]; + return (Some(Token::SingleQuote { + val: &old_remaining[..len], + start_pos: old_current, + })); + } + '"' => {} + _ => {} + } + + Some(Token::Thingy { + val: state.input, + start_pos: 0, + }) + }) +} + +fn main() {}