Added: Rust parser WIP
This commit is contained in:
parent
3ee1bed44e
commit
b38a1cba97
3 changed files with 151 additions and 0 deletions
7
rust/parser/Cargo.lock
generated
Normal file
7
rust/parser/Cargo.lock
generated
Normal file
|
|
@ -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"
|
||||
8
rust/parser/Cargo.toml
Normal file
8
rust/parser/Cargo.toml
Normal file
|
|
@ -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]
|
||||
136
rust/parser/src/main.rs
Normal file
136
rust/parser/src/main.rs
Normal file
|
|
@ -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<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,
|
||||
}
|
||||
|
||||
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<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 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() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue