Added: Stdme as dependency
This commit is contained in:
parent
e1659508c6
commit
78f0707574
11 changed files with 11 additions and 447 deletions
6
.gitmodules
vendored
6
.gitmodules
vendored
|
|
@ -1,3 +1,3 @@
|
|||
[submodule "stdme"]
|
||||
path = stdme
|
||||
url = git@github.com:maix0/stdme.git
|
||||
[submodule "shcat_c/stdme"]
|
||||
path = shcat_c/stdme
|
||||
url = git@github.com:Maix0/stdme.git
|
||||
|
|
|
|||
1
rust/parser/.gitignore
vendored
1
rust/parser/.gitignore
vendored
|
|
@ -1 +0,0 @@
|
|||
/target
|
||||
7
rust/parser/Cargo.lock
generated
7
rust/parser/Cargo.lock
generated
|
|
@ -1,7 +0,0 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "parser-rs"
|
||||
version = "0.1.0"
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
[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]
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* enum.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/03/28 12:44:05 by rparodi #+# #+# */
|
||||
/* Updated: 2024/03/28 13:09:06 by rparodi ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef ENUM_H
|
||||
#define ENUM_H
|
||||
|
||||
#include "./rust_type.h"
|
||||
|
||||
enum e_separator_op
|
||||
{
|
||||
Semi,
|
||||
Fork,
|
||||
};
|
||||
|
||||
enum e_pipeline_kind
|
||||
{
|
||||
Or,
|
||||
And,
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* rust_type.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/03/28 12:50:51 by rparodi #+# #+# */
|
||||
/* Updated: 2024/03/28 12:52:53 by rparodi ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef RUST_TYPE_H
|
||||
#define RUST_TYPE_H
|
||||
|
||||
# define bool int
|
||||
# define true 1
|
||||
# define false 0
|
||||
# define u8 unsigned char
|
||||
# define u16 unsigned short
|
||||
# define u32 unsigned int
|
||||
# define u64 unsigned long long
|
||||
# define i8 char
|
||||
# define i16 short
|
||||
# define i32 int
|
||||
# define i64 long long
|
||||
# define usize size_t
|
||||
# define isize ssize_t
|
||||
# define f32 float
|
||||
# define f64 double
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* shcat.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/03/28 12:42:55 by rparodi #+# #+# */
|
||||
/* Updated: 2024/03/28 12:53:50 by rparodi ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef SHCAT_H
|
||||
#define SHCAT_H
|
||||
|
||||
# include <unistd.h>
|
||||
# include <fcntl.h>
|
||||
# include <stdlib.h>
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/wait.h>
|
||||
# include <stdlib.h>
|
||||
# include <stdarg.h>
|
||||
# include <stddef.h>
|
||||
|
||||
# include "./enum.h"
|
||||
# include "./rust_type.h"
|
||||
#endif
|
||||
|
|
@ -1,331 +0,0 @@
|
|||
#![allow(dead_code)]
|
||||
use std::{borrow::Cow, collections::VecDeque, convert::Infallible as Never, pin::Pin};
|
||||
|
||||
type WORD = String;
|
||||
type Rule2 = String;
|
||||
type Rule3 = String;
|
||||
|
||||
struct SourceFile {
|
||||
cmds: Vec<CompleteCommands>,
|
||||
}
|
||||
|
||||
struct CompleteCommands {
|
||||
// each Pipeline Must have a Separator, but the
|
||||
// last Pipeline is optional
|
||||
list: Vec<(Pipeline, Option<SeparatorOp>)>,
|
||||
}
|
||||
|
||||
enum SeparatorOp {
|
||||
Semi, /* ; */
|
||||
Fork, /* & */
|
||||
}
|
||||
|
||||
struct Pipeline {
|
||||
bang: bool, // placed before the seqence
|
||||
kind: Option<PipelineKind>, // placed after the seqence
|
||||
seq: Vec<Commands>, // each cmd are piped into the next
|
||||
}
|
||||
|
||||
enum PipelineKind {
|
||||
Or, /* || */
|
||||
And, /* && */
|
||||
}
|
||||
|
||||
enum Commands {
|
||||
Simple(SimpleCommand),
|
||||
Compound(Never),
|
||||
FuncDef(Never),
|
||||
}
|
||||
|
||||
struct SimpleCommand {
|
||||
prefix: Vec<CmdPrefix>,
|
||||
cmd: Vec<WORD>, // First is rule 7a, then 7b
|
||||
suffix: Vec<CmdSuffix>,
|
||||
}
|
||||
|
||||
enum CmdPrefix {
|
||||
IoRedirect(IoRedirect),
|
||||
Assigment(Assigment),
|
||||
}
|
||||
|
||||
enum CmdSuffix {
|
||||
IoRedirect(IoRedirect),
|
||||
Word(WORD),
|
||||
}
|
||||
|
||||
struct IoRedirect {
|
||||
io_file: Option<usize>,
|
||||
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,
|
||||
invalid_quote: bool,
|
||||
_marker: std::marker::PhantomPinned,
|
||||
}
|
||||
|
||||
impl<'input> TokenizerState<'input> {
|
||||
fn new(input: &'input str) -> Self {
|
||||
Self {
|
||||
current_pos: 0,
|
||||
remaining: input,
|
||||
invalid_quote: false,
|
||||
input,
|
||||
_marker: std::marker::PhantomPinned,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cow<'input, str> is either a owned string (so it'll have to be free'd, basically it is an `String`
|
||||
// or it is an borrow string, so an &'input str, which doesn't need to be free (or at least by us)
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum Token<'input> {
|
||||
SingleQuote {
|
||||
val: Cow<'input, str>,
|
||||
start_pos: usize,
|
||||
},
|
||||
DoubleQuote {
|
||||
val: Cow<'input, str>,
|
||||
start_pos: usize,
|
||||
},
|
||||
WhiteSpace {
|
||||
val: Cow<'input, str>,
|
||||
start_pos: usize,
|
||||
},
|
||||
Word {
|
||||
val: Cow<'input, str>,
|
||||
start_pos: usize,
|
||||
},
|
||||
}
|
||||
|
||||
fn tokenizer<'state, 'input: 'state>(
|
||||
state: &'state mut TokenizerState<'input>,
|
||||
) -> impl Iterator<Item = Token<'input>> + '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 mut escaped = false;
|
||||
|
||||
let Some(chr) = chars.next() else {
|
||||
return None;
|
||||
};
|
||||
match chr {
|
||||
'\'' => {
|
||||
while let Some(s) = chars.peek().copied() {
|
||||
if s == '\'' {
|
||||
break;
|
||||
}
|
||||
len += 1;
|
||||
chars.next();
|
||||
}
|
||||
let skip = chars.peek() == Some(&'\'');
|
||||
state.invalid_quote |= !skip;
|
||||
let old_current = state.current_pos;
|
||||
state.current_pos += len;
|
||||
let old_remaining = state.remaining;
|
||||
state.remaining = &state.remaining[(len + skip as usize)..];
|
||||
return Some(Token::SingleQuote {
|
||||
val: old_remaining[1..len].into(),
|
||||
start_pos: old_current,
|
||||
});
|
||||
}
|
||||
'"' => {
|
||||
while let Some(s) = chars.peek().copied() {
|
||||
if !escaped && s == '\"' {
|
||||
break;
|
||||
}
|
||||
len += 1;
|
||||
escaped = chars.next() == Some('\\');
|
||||
}
|
||||
let skip = chars.peek() == Some(&'\"');
|
||||
state.invalid_quote |= !skip;
|
||||
let old_current = state.current_pos;
|
||||
state.current_pos += len;
|
||||
let old_remaining = state.remaining;
|
||||
state.remaining = &state.remaining[(len + skip as usize)..];
|
||||
return Some(Token::DoubleQuote {
|
||||
val: old_remaining[1..len].into(),
|
||||
start_pos: old_current,
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
let was_whitespace = chr.is_ascii_whitespace();
|
||||
while let Some(&chr) = chars.peek() {
|
||||
if chr.is_ascii_whitespace() && !escaped && !was_whitespace {
|
||||
let old_current = state.current_pos;
|
||||
state.current_pos += len;
|
||||
let old_remaining = state.remaining;
|
||||
state.remaining = &state.remaining[len..];
|
||||
return Some(Token::Word {
|
||||
val: old_remaining[..len].into(),
|
||||
start_pos: old_current,
|
||||
});
|
||||
} else if !chr.is_ascii_whitespace() && was_whitespace {
|
||||
let old_current = state.current_pos;
|
||||
state.current_pos += len;
|
||||
let old_remaining = state.remaining;
|
||||
state.remaining = &state.remaining[len..];
|
||||
return Some(Token::WhiteSpace {
|
||||
val: old_remaining[..len].into(),
|
||||
start_pos: old_current,
|
||||
});
|
||||
}
|
||||
len += 1;
|
||||
escaped = chars.next() == Some('\\');
|
||||
}
|
||||
let old_current = state.current_pos;
|
||||
state.current_pos += len;
|
||||
let old_remaining = state.remaining;
|
||||
state.remaining = &state.remaining[len..];
|
||||
Some(if was_whitespace {
|
||||
Token::WhiteSpace {
|
||||
val: old_remaining[..len].into(),
|
||||
start_pos: old_current,
|
||||
}
|
||||
} else {
|
||||
Token::Word {
|
||||
val: old_remaining[..len].into(),
|
||||
start_pos: old_current,
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// This isn't a C thingy, it is just needed to make rust happy
|
||||
|
||||
struct TokenizerWrapper<'input> {
|
||||
_marker: std::marker::PhantomPinned,
|
||||
first_pass: TokenizerState<'input>,
|
||||
iter: Box<dyn Iterator<Item = Token<'input>> + 'input>,
|
||||
}
|
||||
|
||||
impl<'input> TokenizerWrapper<'input> {
|
||||
fn new(s: TokenizerState<'input>) -> Pin<Box<Self>> {
|
||||
let mut value = Box::new(std::mem::MaybeUninit::<Self>::uninit());
|
||||
unsafe {
|
||||
let ptr = value.as_mut_ptr();
|
||||
std::ptr::write(std::ptr::addr_of_mut!((*ptr).first_pass), s);
|
||||
std::ptr::write(
|
||||
std::ptr::addr_of_mut!((*ptr).iter),
|
||||
Box::new(tokenizer(&mut *std::ptr::addr_of_mut!((*ptr).first_pass))),
|
||||
);
|
||||
std::mem::transmute(Pin::new_unchecked(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'input> TokenizerWrapper<'input> {
|
||||
fn next(self: &mut Pin<Box<Self>>) -> Option<Token<'input>> {
|
||||
unsafe { Pin::into_inner_unchecked(self.as_mut()).iter.next() }
|
||||
}
|
||||
}
|
||||
|
||||
// end of rust thingy
|
||||
|
||||
struct ExpenderState<'input> {
|
||||
// These will be inserted when a substitution is made, like $HOME
|
||||
// if it is "$HOME", then no splitting should be done, so if there is any stuff that needs to
|
||||
// be pushed, then push it, otherwise get the next token from `iter`, expend if needed and
|
||||
// voila
|
||||
need_push: VecDeque<ExpendedToken<'input>>,
|
||||
// This is because of the way I wrote the rust
|
||||
// stuff, returning iterator instead of an token everytime I call a function and stuff, it
|
||||
// shouldn't be reflected into the C code, as we will just call 'get_next_token(&state)' and it
|
||||
// will give us the next token (or EOF if no more token are present)
|
||||
tokenizer: Pin<Box<TokenizerWrapper<'input>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum ExpendedToken<'input> {
|
||||
SingleQuote {
|
||||
val: Cow<'input, str>,
|
||||
start_pos: usize,
|
||||
},
|
||||
DoubleQuote {
|
||||
val: Cow<'input, str>,
|
||||
start_pos: usize,
|
||||
},
|
||||
WhiteSpace {
|
||||
val: Cow<'input, str>,
|
||||
start_pos: usize,
|
||||
},
|
||||
Word {
|
||||
val: Cow<'input, str>,
|
||||
start_pos: usize,
|
||||
},
|
||||
}
|
||||
|
||||
impl<'input> ExpenderState<'input> {
|
||||
fn new(input: &'input str) -> Self {
|
||||
let wrapper = TokenizerWrapper::new(TokenizerState::new(input));
|
||||
|
||||
Self {
|
||||
need_push: VecDeque::new(),
|
||||
tokenizer: wrapper,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn expend<'state, 'input: 'state>(
|
||||
input: &'state mut ExpenderState<'input>,
|
||||
) -> impl Iterator<Item = ExpendedToken<'input>> + 'state {
|
||||
std::iter::from_fn(|| {
|
||||
if !input.need_push.is_empty() {
|
||||
input.need_push.pop_front()
|
||||
} else {
|
||||
input.tokenizer.next().map(|t| match t {
|
||||
Token::Word { val, start_pos } => ExpendedToken::Word { val, start_pos },
|
||||
Token::DoubleQuote { val, start_pos } => {
|
||||
ExpendedToken::DoubleQuote { val, start_pos }
|
||||
}
|
||||
Token::SingleQuote { val, start_pos } => {
|
||||
ExpendedToken::SingleQuote { val, start_pos }
|
||||
}
|
||||
Token::WhiteSpace { val, start_pos } => {
|
||||
ExpendedToken::WhiteSpace { val, start_pos }
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn main() {
|
||||
for line in std::io::stdin().lines() {
|
||||
let line = line.unwrap();
|
||||
let mut state = ExpenderState::new(&line);
|
||||
println!("line is = '{line}'");
|
||||
println!("token are = {:?}", expend(&mut state).collect::<Vec<_>>());
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
# By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ #
|
||||
# +#+#+#+#+#+ +#+ #
|
||||
# Created: 2023/11/12 11:05:05 by rparodi #+# #+# #
|
||||
# Updated: 2024/04/13 20:18:33 by rparodi ### ########.fr #
|
||||
# Updated: 2024/04/28 17:05:10 by maiboyer ### ########.fr #
|
||||
# #
|
||||
# **************************************************************************** #
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ CC = cc
|
|||
RM = rm -rf
|
||||
|
||||
# Flags
|
||||
CFLAGS = -Werror -Wextra -Wall -Wno-unused-command-line-argument -g3 -MMD -lreadline
|
||||
CFLAGS = -Werror -Wextra -Wall -Wno-unused-command-line-argument -g3 -MMD -lreadline -I./libft
|
||||
|
||||
# Sources
|
||||
LIB = ./libft/ft_bzero.c \
|
||||
|
|
@ -84,7 +84,7 @@ fclean: clean
|
|||
re: header fclean all
|
||||
|
||||
# Dependences for all
|
||||
$(NAME): $(OBJ) $(LIB_OBJ)
|
||||
$(NAME): $(OBJ) $(LIB_OBJ) $(OBJDIRNAME)/libme.a
|
||||
@mkdir -p $(OBJDIRNAME)
|
||||
@mkdir -p $(OBJDIRNAME)/$(LIBDIRNAME)
|
||||
@mkdir -p $(OBJDIRNAME)/$(SRCDIRNAME)
|
||||
|
|
@ -128,6 +128,10 @@ footer:
|
|||
@printf "$(GOLD) '\"' '\"'$(END)\n"
|
||||
@printf ' $(GREY)The compilation is$(END) $(GOLD)finish$(END)\n $(GREY)Have a good $(END)$(GOLD)correction !$(END)\n'
|
||||
|
||||
$(OBJDIRNAME)/libme.a:
|
||||
@$(MAKE) --no-print-directory -C ./stdme/ LIB_NAME="$(realpath ./$(stdme))/" "BUILD_DIR=$(shell realpath ./$(OBJDIRNAME))"
|
||||
|
||||
|
||||
pull:
|
||||
@printf "$(GREEN)Pulling Submodules$(END)\n"
|
||||
@git submodule init
|
||||
|
|
|
|||
1
shcat_c/stdme
Submodule
1
shcat_c/stdme
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit dc3c8ff9dc6f396a8fefd4ad89883e5285171b23
|
||||
1
stdme
1
stdme
|
|
@ -1 +0,0 @@
|
|||
Subproject commit b3ec36536db39e871e06e6073c05bf2f965adf99
|
||||
Loading…
Add table
Add a link
Reference in a new issue