From a9c21f23f004cc41fdba52da365bedf5cab8adfc Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Wed, 22 Dec 2021 21:42:39 -0500 Subject: parse quoted strings --- src/parse.rs | 26 ++++++++++++++------------ src/shell.pest | 15 +++++++++++++-- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/parse.rs b/src/parse.rs index 4ddffba..03b865c 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -11,17 +11,19 @@ pub struct Word { } impl Word { - fn new(word: &str) -> Self { - Self { - word: word.to_string(), - interpolate: true, - } - } - - fn literal(word: &str) -> Self { + fn build_ast(pair: pest::iterators::Pair) -> Self { + assert!(matches!(pair.as_rule(), Rule::word)); + let word = pair.into_inner().next().unwrap(); + assert!(matches!( + word.as_rule(), + Rule::bareword | Rule::single_string | Rule::double_string + )); Self { - word: word.to_string(), - interpolate: false, + word: word.as_str().to_string(), + interpolate: matches!( + word.as_rule(), + Rule::bareword | Rule::double_string + ), } } } @@ -36,8 +38,8 @@ impl Exe { fn build_ast(pair: pest::iterators::Pair) -> Self { assert!(matches!(pair.as_rule(), Rule::exe)); let mut iter = pair.into_inner(); - let exe = Word::new(iter.next().unwrap().as_str()); - let args = iter.map(|word| Word::new(word.as_str())).collect(); + let exe = Word::build_ast(iter.next().unwrap()); + let args = iter.map(Word::build_ast).collect(); Self { exe, args } } diff --git a/src/shell.pest b/src/shell.pest index 49a84b4..7744873 100644 --- a/src/shell.pest +++ b/src/shell.pest @@ -1,5 +1,16 @@ -char = @{ !("|" | ";" | WHITESPACE) ~ ANY } -word = @{ char+ } +bareword_char = @{ !("|" | ";" | "\"" | "'" | WHITESPACE | COMMENT) ~ ANY } +single_string_char = @{ "\\'" | (!"'" ~ ANY) } +double_string_char = @{ "\\\"" | (!"\"" ~ ANY) } + +bareword = @{ bareword_char+ } +single_string = @{ single_string_char+ } +double_string = @{ double_string_char+ } + +word = { + bareword | + "'" ~ single_string ~ "'" | + "\"" ~ double_string ~ "\"" +} exe = { word+ } pipeline = { exe ~ ("|" ~ exe)* } -- cgit v1.2.3-54-g00ecf