From b74daa2e602c95292e3c057ba72b885df4f89ff3 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Sat, 25 May 2019 23:54:41 -0700 Subject: [PATCH] A real parser (lalrpop) --- .cargo/config | 0 Cargo.lock | 53 + Cargo.toml | 4 + Makefile.toml | 9 + src/cli.rs | 77 +- src/commands/classified.rs | 16 +- src/commands/split.rs | 16 +- src/commands/where_.rs | 25 +- src/context.rs | 31 +- src/errors.rs | 11 +- src/format/generic.rs | 8 + src/main.rs | 1 + src/object/base.rs | 61 +- src/object/desc.rs | 10 + src/object/dict.rs | 2 +- src/parser.rs | 18 +- src/parser/parse.rs | 144 --- src/parser/parser.lalrpop | 56 + src/parser/parser.rs | 2109 ++++++++++++++++++++++++++++++++++++ src/parser/registry.rs | 21 + src/parser/tokens.rs | 128 +++ src/prelude.rs | 2 +- src/shell/completer.rs | 9 +- src/shell/helper.rs | 4 +- 24 files changed, 2599 insertions(+), 216 deletions(-) create mode 100644 .cargo/config create mode 100644 Makefile.toml delete mode 100644 src/parser/parse.rs create mode 100644 src/parser/parser.lalrpop create mode 100644 src/parser/parser.rs create mode 100644 src/parser/registry.rs create mode 100644 src/parser/tokens.rs diff --git a/.cargo/config b/.cargo/config new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Cargo.lock b/Cargo.lock index f0618da4c5..0f8a923f5b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -639,6 +639,18 @@ dependencies = [ "syn 0.15.34 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "env_logger" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "error-chain" version = "0.12.1" @@ -828,6 +840,11 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "lalrpop-util" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "lazy_static" version = "1.3.0" @@ -985,11 +1002,15 @@ dependencies = [ "futures_codec 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lalrpop-util 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "nom 5.0.0-beta1 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "pancurses 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "prettyprint 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "prettytable-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustyline 4.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "subprocess 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "sysinfo 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1179,6 +1200,16 @@ dependencies = [ "xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "pretty_env_logger" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "prettyprint" version = "0.6.0" @@ -1656,6 +1687,14 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "termcolor" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "termion" version = "1.5.2" @@ -1854,6 +1893,15 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "wincolor" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winreg" version = "0.5.1" @@ -1953,6 +2001,7 @@ dependencies = [ "checksum enum-map-internals 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "38b0bacf3ea7aba18ce84032efc3f0fa29f5c814048b742ab3e64d07d83ac3e8" "checksum enumset 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cac0a22e173f6570a7d69a2ab9e3fe79cf0dcdd0fdb162bfc932b97158f2b2a7" "checksum enumset_derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "01d93b926a992a4a526c2a14e2faf734fdef5bf9d0a52ba69a2ca7d4494c284b" +"checksum env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b61fa891024a945da30a9581546e8cfaf5602c7b3f4c137a2805cf388f92075a" "checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" @@ -1976,6 +2025,7 @@ dependencies = [ "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum lalrpop-util 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9768f55211206d3c17181108d8facb80bdffc1f1e674a67b1dddb2743529ca19" "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" "checksum lexical-core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e82e023e062f1d25f807ad182008fba1b46538e999f908a08cc0c29e084462e" @@ -2014,6 +2064,7 @@ dependencies = [ "checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" "checksum plist 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f4739851c08dd9a62a78beff2edf1a438517268b2c563c42fc6d9d3139e42d2a" +"checksum pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8b3f4e0475def7d9c2e5de8e5a1306949849761e107b360d03e98eafaffd61" "checksum prettyprint 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2705417f8aa07cb6308db42e55623479c1c9667942a4d5e4174c684e5da5590d" "checksum prettytable-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0fd04b170004fa2daccf418a7f8253aaf033c27760b5f225889024cf66d7ac2e" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" @@ -2069,6 +2120,7 @@ dependencies = [ "checksum sysinfo 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "65f0e28a49b7bf142cee89befd7077b40627d7cc70aa8a8acfe03afc26016c33" "checksum term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" "checksum term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5b9a66db815dcfd2da92db471106457082577c3c278d4138ab3e3b4e189327" +"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" "checksum termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dde0593aeb8d47accea5392b39350015b5eccb12c0d98044d856983d89548dea" "checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" @@ -2096,6 +2148,7 @@ dependencies = [ "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +"checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" "checksum winreg 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a27a759395c1195c4cc5cda607ef6f8f6498f64e78f7900f5de0a127a424704a" "checksum xi-unicode 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "12ea8eda4b1eb72f02d148402e23832d56a33f55d8c1b2d5bcdde91d79d47cb1" "checksum xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "541b12c998c5b56aa2b4e6f18f03664eef9a4fd0a246a55594efae6cc2d964b5" diff --git a/Cargo.toml b/Cargo.toml index 60e1f37644..afaa014ba2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,10 @@ tokio-fs = "0.1.6" futures_codec = "0.2.2" term = "0.5.2" bytes = "0.4.12" +log = "0.4.6" +pretty_env_logger = "0.3.0" +lalrpop-util = "0.17.0" +regex = "1.1.6" [dependencies.pancurses] version = "0.16" diff --git a/Makefile.toml b/Makefile.toml new file mode 100644 index 0000000000..f4efcace42 --- /dev/null +++ b/Makefile.toml @@ -0,0 +1,9 @@ +[tasks.lalrpop] +install_crate = { crate_name = "lalrpop", binary = "lalrpop", test_arg = "--help" } +command = "lalrpop" +args = ["src/parser/parser.lalrpop"] + +[tasks.build] +command = "cargo" +args = ["build"] +dependencies = ["lalrpop"] \ No newline at end of file diff --git a/src/cli.rs b/src/cli.rs index 0ec35c094f..c644bf7c30 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,14 +1,17 @@ use crate::prelude::*; use crate::commands::classified::{ - ClassifiedCommand, ClassifiedInputStream, ExternalCommand, InternalCommand, StreamNext, + ClassifiedCommand, ClassifiedInputStream, ClassifiedPipeline, ExternalCommand, InternalCommand, + StreamNext, }; use crate::context::Context; crate use crate::errors::ShellError; crate use crate::format::{EntriesListView, GenericView}; use crate::object::Value; +use crate::parser::{ParsedCommand, Pipeline}; use crate::stream::empty_stream; +use log::debug; use rustyline::error::ReadlineError; use rustyline::{self, ColorMode, Config, Editor}; use std::collections::VecDeque; @@ -32,20 +35,6 @@ impl MaybeOwned<'a, T> { } pub async fn cli() -> Result<(), Box> { - let config = Config::builder().color_mode(ColorMode::Forced).build(); - let h = crate::shell::Helper::new(); - let mut rl: Editor = Editor::with_config(config); - - #[cfg(windows)] - { - let _ = ansi_term::enable_ansi_support(); - } - - rl.set_helper(Some(h)); - if rl.load_history("history.txt").is_err() { - println!("No previous history."); - } - let mut context = Context::basic()?; { @@ -68,6 +57,20 @@ pub async fn cli() -> Result<(), Box> { ]); } + let config = Config::builder().color_mode(ColorMode::Forced).build(); + let h = crate::shell::Helper::new(context.clone_commands()); + let mut rl: Editor = Editor::with_config(config); + + #[cfg(windows)] + { + let _ = ansi_term::enable_ansi_support(); + } + + rl.set_helper(Some(h)); + if rl.load_history("history.txt").is_err() { + println!("No previous history."); + } + loop { let readline = rl.readline(&format!( "{}> ", @@ -141,7 +144,7 @@ async fn process_line(readline: Result, ctx: &mut Context Ok(line) if line.trim() == "" => LineResult::Success(line.clone()), Ok(line) => { - let result = match crate::parser::shell_parser(&line) { + let result = match crate::parser::parse(&line, &ctx.registry()) { Err(err) => { return LineResult::Error(format!("{:?}", err)); } @@ -149,17 +152,14 @@ async fn process_line(readline: Result, ctx: &mut Context Ok(val) => val, }; - let parsed: Result, _> = result - .1 - .into_iter() - .map(|item| classify_command(&item, ctx)) - .collect(); + debug!("=== Parsed ==="); + debug!("{:#?}", result); - let parsed = parsed?; + let pipeline = classify_pipeline(&result, ctx)?; let mut input = ClassifiedInputStream::new(); - let mut iter = parsed.into_iter().peekable(); + let mut iter = pipeline.commands.into_iter().peekable(); loop { let item: Option = iter.next(); @@ -194,7 +194,7 @@ async fn process_line(readline: Result, ctx: &mut Context ( Some(ClassifiedCommand::Internal(_)), Some(ClassifiedCommand::External(_)), - ) => unimplemented!(), + ) => return LineResult::Error(format!("Unimplemented Internal -> External",)), ( Some(ClassifiedCommand::External(left)), @@ -245,17 +245,34 @@ async fn process_line(readline: Result, ctx: &mut Context } } +fn classify_pipeline( + pipeline: &Pipeline, + context: &Context, +) -> Result { + let commands: Result, _> = pipeline + .commands + .iter() + .cloned() + .map(|item| classify_command(&item, context)) + .collect(); + + Ok(ClassifiedPipeline { + commands: commands?, + }) +} + fn classify_command( - command: &[crate::parser::Item], + command: &ParsedCommand, context: &Context, ) -> Result { - let command_name = &command[0].name()?; + let command_name = &command.name[..]; + let args = &command.args; - let arg_list: Vec = command[1..].iter().map(|i| i.as_value()).collect(); - let arg_list_strings: Vec = command[1..].iter().map(|i| i.print()).collect(); + let arg_list: Vec = args.iter().map(|i| Value::from_expr(i)).collect(); + let arg_list_strings: Vec = args.iter().map(|i| i.print()).collect(); - match *command_name { - other => match context.has_command(*command_name) { + match command_name { + other => match context.has_command(command_name) { true => { let command = context.get_command(command_name); Ok(ClassifiedCommand::Internal(InternalCommand { diff --git a/src/commands/classified.rs b/src/commands/classified.rs index 8376a589ca..bd80ab908a 100644 --- a/src/commands/classified.rs +++ b/src/commands/classified.rs @@ -1,10 +1,9 @@ use crate::prelude::*; -use futures::TryStreamExt; -use futures_codec::{Encoder, Decoder, Framed}; +use bytes::{BufMut, BytesMut}; +use futures_codec::{Decoder, Encoder, Framed}; +use std::io::{Error, ErrorKind}; use std::sync::Arc; use subprocess::Exec; -use std::io::{Error, ErrorKind}; -use bytes::{BufMut, BytesMut}; /// A simple `Codec` implementation that splits up data into lines. pub struct LinesCodec {} @@ -37,7 +36,7 @@ impl Decoder for LinesCodec { .map(Some) .map_err(|e| Error::new(ErrorKind::InvalidData, e)) } - _ => Ok(None) + _ => Ok(None), } } } @@ -70,6 +69,10 @@ impl ClassifiedInputStream { } } +crate struct ClassifiedPipeline { + crate commands: Vec, +} + crate enum ClassifiedCommand { Internal(InternalCommand), External(ExternalCommand), @@ -127,8 +130,7 @@ impl ExternalCommand { cmd.push_str(" "); cmd.push_str(&arg); } - let process = Exec::shell(&cmd) - .cwd(context.env.lock().unwrap().cwd()); + let process = Exec::shell(&cmd).cwd(context.env.lock().unwrap().cwd()); let mut process = match stream_next { StreamNext::Last => process, diff --git a/src/commands/split.rs b/src/commands/split.rs index 5246e6849c..be6db7efcc 100644 --- a/src/commands/split.rs +++ b/src/commands/split.rs @@ -1,6 +1,7 @@ use crate::errors::ShellError; -use crate::object::Value; +use crate::object::{Primitive, Value}; use crate::prelude::*; +use log::debug; // TODO: "Amount remaining" wrapper @@ -13,18 +14,27 @@ pub fn split(args: CommandArgs) -> Result { .map(move |v| match v { Value::Primitive(Primitive::String(s)) => { let splitter = args[0].as_string().unwrap(); + debug!("splitting with {:?}", splitter); let split_result: Vec<_> = s.split(&splitter).filter(|s| s.trim() != "").collect(); + debug!("split result = {:?}", split_result); + if split_result.len() == (args.len() - 1) { let mut dict = crate::object::Dictionary::default(); for (k, v) in split_result.iter().zip(args.iter().skip(1)) { - dict.add(v.as_string().unwrap(), Value::Primitive(Primitive::String(k.to_string()))); + dict.add( + v.as_string().unwrap(), + Value::Primitive(Primitive::String(k.to_string())), + ); } ReturnValue::Value(Value::Object(dict)) } else { let mut dict = crate::object::Dictionary::default(); for k in args.iter().skip(1) { - dict.add(k.as_string().unwrap().trim(), Value::Primitive(Primitive::String("".to_string()))); + dict.add( + k.as_string().unwrap().trim(), + Value::Primitive(Primitive::String("".to_string())), + ); } ReturnValue::Value(Value::Object(dict)) } diff --git a/src/commands/where_.rs b/src/commands/where_.rs index 3db875f756..b97b75b02e 100644 --- a/src/commands/where_.rs +++ b/src/commands/where_.rs @@ -7,24 +7,15 @@ pub fn r#where(args: CommandArgs) -> Result { return Err(ShellError::string("select requires a field")); } - let field: Result = args.args[0].as_string(); - let field = field?; + let operation = args.args[0].as_operation()?; + let field = operation.left.as_string()?; + let operator = operation.operator; + let right = operation.right; let input = args.input; - let operator = args.args[1].copy(); - match operator { - Value::Primitive(Primitive::Operator(operator)) => { - let right = args.args[2].copy(); + let objects = input + .filter(move |item| futures::future::ready(find(&item, &field, &operator, &right))) + .map(|item| ReturnValue::Value(item.copy())); - let objects = input - .filter(move |item| futures::future::ready(find(&item, &field, &operator, &right))) - .map(|item| ReturnValue::Value(item.copy())); - - Ok(objects.boxed()) - } - x => { - println!("{:?}", x); - Err(ShellError::string("expected a comparison operator")) - } - } + Ok(objects.boxed()) } diff --git a/src/context.rs b/src/context.rs index 6bea845ca4..fd4ee18228 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,10 +1,12 @@ +use crate::parser::{CommandConfig, CommandRegistry}; use crate::prelude::*; +use indexmap::IndexMap; use std::error::Error; use std::sync::Arc; pub struct Context { - commands: indexmap::IndexMap>, + commands: IndexMap>, crate host: Arc>, crate env: Arc>, } @@ -24,6 +26,16 @@ impl Context { } } + pub fn clone_commands(&self) -> indexmap::IndexMap> { + self.commands.clone() + } + + pub fn registry(&self) -> CommandMap { + CommandMap { + commands: self.clone_commands(), + } + } + crate fn has_command(&self, name: &str) -> bool { self.commands.contains_key(name) } @@ -48,3 +60,20 @@ impl Context { command.run(command_args) } } + +pub struct CommandMap { + #[allow(unused)] + commands: IndexMap>, +} + +impl CommandRegistry for CommandMap { + fn get(&self, name: &str) -> CommandConfig { + CommandConfig { + name: name.to_string(), + mandatory_positional: vec![], + optional_positional: vec![], + rest_positional: true, + named: IndexMap::new(), + } + } +} diff --git a/src/errors.rs b/src/errors.rs index b18f3ff55e..2f4f6c2127 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -3,7 +3,7 @@ use crate::prelude::*; use derive_new::new; -#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, new)] +#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, new, Clone)] pub struct ShellError { title: String, error: Value, @@ -60,3 +60,12 @@ impl std::convert::From for ShellError { } } } + +impl std::convert::From> for ShellError { + fn from(input: nom::Err<(&str, nom::error::ErrorKind)>) -> ShellError { + ShellError { + title: format!("{:?}", input), + error: Value::nothing(), + } + } +} diff --git a/src/format/generic.rs b/src/format/generic.rs index 02383dd000..8586fd2d17 100644 --- a/src/format/generic.rs +++ b/src/format/generic.rs @@ -43,6 +43,14 @@ impl RenderView for GenericView<'value> { Ok(()) } + Value::Operation(o) => { + host.stdout(&format!( + "Unexpectedly trying to print an operation: {:?}", + o + )); + Ok(()) + } + Value::Error(e) => { host.stdout(&format!("{:?}", e)); Ok(()) diff --git a/src/main.rs b/src/main.rs index 8a5da7c13f..9debdd2830 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,6 +19,7 @@ mod stream; use std::error::Error; fn main() -> Result<(), Box> { + pretty_env_logger::init(); futures::executor::block_on(crate::cli::cli())?; Ok(()) } diff --git a/src/object/base.rs b/src/object/base.rs index f708b0f044..0439aba77c 100644 --- a/src/object/base.rs +++ b/src/object/base.rs @@ -1,10 +1,11 @@ use crate::errors::ShellError; use crate::object::DataDescriptor; -use crate::parser::parse::Operator; +use crate::parser::tokens::{self, Operator}; use crate::prelude::*; use ansi_term::Color; use chrono::{DateTime, Utc}; use chrono_humanize::Humanize; +use derive_new::new; use ordered_float::OrderedFloat; use std::time::SystemTime; @@ -20,7 +21,6 @@ pub enum Primitive { String(String), Boolean(bool), Date(DateTime), - Operator(Operator), } impl Primitive { @@ -51,27 +51,64 @@ impl Primitive { (false, Some(_)) => format!(""), }, Primitive::Date(d) => format!("{}", d.humanize()), - Primitive::Operator(o) => o.print(), } } } -#[derive(Debug, Ord, PartialOrd, Eq, PartialEq)] +#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone, new)] +pub struct Operation { + crate left: Value, + crate operator: Operator, + crate right: Value, +} + +#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone)] pub enum Value { Primitive(Primitive), Object(crate::object::Dictionary), List(Vec), + Operation(Box), #[allow(unused)] Error(Box), } impl Value { + crate fn from_leaf(leaf: &tokens::Leaf) -> Value { + use tokens::*; + + match leaf { + Leaf::String(s) => Value::string(s), + Leaf::Bare(s) => Value::string(s), + Leaf::Boolean(b) => Value::boolean(*b), + Leaf::Int(i) => Value::int(*i), + } + } + + crate fn from_expr(expr: &tokens::Expression) -> Value { + use tokens::*; + + match expr { + Expression::Leaf(leaf) => Value::from_leaf(leaf), + + Expression::Binary(Binary { + left, + operator, + right, + }) => Value::Operation(Box::new(Operation::new( + Value::from_leaf(left), + *operator, + Value::from_leaf(right), + ))), + } + } + crate fn data_descriptors(&self) -> Vec { match self { Value::Primitive(_) => vec![DataDescriptor::value_of()], Value::Object(o) => o.data_descriptors(), Value::List(_) => vec![], + Value::Operation(_) => vec![], Value::Error(_) => vec![], } } @@ -81,6 +118,7 @@ impl Value { Value::Primitive(_) => MaybeOwned::Owned(Value::nothing()), Value::Object(o) => o.get_data_by_key(name), Value::List(_) => MaybeOwned::Owned(Value::nothing()), + Value::Operation(_) => MaybeOwned::Owned(Value::nothing()), Value::Error(_) => MaybeOwned::Owned(Value::nothing()), } } @@ -90,6 +128,7 @@ impl Value { p @ Value::Primitive(_) => MaybeOwned::Borrowed(p), Value::Object(o) => o.get_data(desc), Value::List(_) => MaybeOwned::Owned(Value::nothing()), + Value::Operation(_) => MaybeOwned::Owned(Value::nothing()), Value::Error(_) => MaybeOwned::Owned(Value::nothing()), } } @@ -102,6 +141,7 @@ impl Value { let list = l.iter().map(|i| i.copy()).collect(); Value::List(list) } + Value::Operation(o) => Value::Operation(o.clone()), Value::Error(e) => Value::Error(Box::new(e.copy_error())), } } @@ -111,6 +151,7 @@ impl Value { Value::Primitive(p) => p.format(field_name), Value::Object(_) => format!("[object Object]"), Value::List(_) => format!("[list List]"), + Value::Operation(_) => format!("[operation Operation]"), Value::Error(e) => format!("{}", e), } } @@ -127,6 +168,18 @@ impl Value { } } + crate fn as_operation(&self) -> Result { + match self { + Value::Operation(o) => Ok(*o.clone()), + + // TODO: this should definitely be more general with better errors + other => Err(ShellError::string(format!( + "Expected operation, got {:?}", + other + ))), + } + } + crate fn as_int(&self) -> Result { match self { Value::Primitive(Primitive::Int(i)) => Ok(*i), diff --git a/src/object/desc.rs b/src/object/desc.rs index a7def78f04..d34b64fe6f 100644 --- a/src/object/desc.rs +++ b/src/object/desc.rs @@ -79,6 +79,16 @@ impl DescriptorName { } } +impl Clone for DataDescriptor { + fn clone(&self) -> DataDescriptor { + DataDescriptor { + name: self.name.clone(), + readonly: self.readonly, + ty: self.ty.copy(), + } + } +} + impl DataDescriptor { crate fn value_of() -> DataDescriptor { DataDescriptor { diff --git a/src/object/dict.rs b/src/object/dict.rs index 2b2e4b7cc1..e3d9914ff3 100644 --- a/src/object/dict.rs +++ b/src/object/dict.rs @@ -5,7 +5,7 @@ use crate::object::{Primitive, Value}; use indexmap::IndexMap; use std::cmp::{Ordering, PartialOrd}; -#[derive(Debug, Default, Eq, PartialEq)] +#[derive(Debug, Default, Eq, PartialEq, Clone)] pub struct Dictionary { entries: IndexMap, } diff --git a/src/parser.rs b/src/parser.rs index 909d77fdd8..825346bda9 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,4 +1,18 @@ crate mod completer; -crate mod parse; +crate mod parser; +crate mod registry; +crate mod tokens; -crate use self::parse::{shell_parser, Item}; +crate use registry::{CommandConfig, CommandRegistry}; +crate use tokens::{ParsedCommand, Pipeline}; + +use crate::errors::ShellError; +use parser::PipelineParser; + +pub fn parse(input: &str, _registry: &dyn CommandRegistry) -> Result { + let parser = PipelineParser::new(); + + parser + .parse(input) + .map_err(|e| ShellError::string(format!("{:?}", e))) +} diff --git a/src/parser/parse.rs b/src/parser/parse.rs deleted file mode 100644 index c379eab6d4..0000000000 --- a/src/parser/parse.rs +++ /dev/null @@ -1,144 +0,0 @@ -use crate::prelude::*; -use nom::branch::alt; -use nom::bytes::complete::{escaped, is_a, is_not, tag}; -use nom::character::complete::one_of; -use nom::multi::separated_list; -use nom::sequence::{preceded, terminated}; -use nom::IResult; -use nom::{complete, named, ws}; -use std::str::FromStr; - -#[derive(Debug, Clone)] -pub enum Item { - Quoted(String), - Bare(String), - Int(i64), - Boolean(bool), - Operator(Operator), -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub enum Operator { - Equal, - NotEqual, - LessThan, - GreaterThan, - LessThanOrEqual, - GreaterThanOrEqual, -} - -impl Operator { - pub fn print(&self) -> String { - match *self { - Operator::Equal => "==".to_string(), - Operator::NotEqual => "!=".to_string(), - Operator::LessThan => "<".to_string(), - Operator::GreaterThan => ">".to_string(), - Operator::LessThanOrEqual => "<=".to_string(), - Operator::GreaterThanOrEqual => ">=".to_string(), - } - } -} - -impl FromStr for Operator { - type Err = (); - fn from_str(input: &str) -> Result::Err> { - match input { - "==" => Ok(Operator::Equal), - "!=" => Ok(Operator::NotEqual), - "<" => Ok(Operator::LessThan), - ">" => Ok(Operator::GreaterThan), - "<=" => Ok(Operator::LessThanOrEqual), - ">=" => Ok(Operator::GreaterThanOrEqual), - _ => Err(()), - } - } -} - -impl Item { - crate fn as_value(&self) -> Value { - match self { - Item::Quoted(s) => Value::Primitive(Primitive::String(s.clone())), - Item::Bare(s) => Value::Primitive(Primitive::String(s.clone())), - Item::Int(i) => Value::Primitive(Primitive::Int(*i)), - Item::Boolean(b) => Value::Primitive(Primitive::Boolean(*b)), - Item::Operator(o) => Value::Primitive(Primitive::Operator(o.clone())), - } - } - - pub fn print(&self) -> String { - match self { - Item::Bare(s) => format!("{}", s), - Item::Quoted(s) => format!("{}", s), - Item::Int(i) => format!("{:?}", i), - Item::Boolean(b) => format!("{:?}", b), - Item::Operator(o) => o.print(), - } - } -} - -impl Item { - crate fn name(&self) -> Result<&str, ShellError> { - match self { - Item::Quoted(s) => Ok(s), - Item::Bare(s) => Ok(s), - Item::Boolean(i) => Err(ShellError::string(format!("{} is not a valid command", i))), - Item::Int(i) => Err(ShellError::string(format!("{} is not a valid command", i))), - Item::Operator(x) => Err(ShellError::string(format!( - "{:?} is not a valid command", - x - ))), - } - } -} - -fn esc(s: &str) -> IResult<&str, &str> { - escaped(is_not("\\\""), '\\', one_of("\"n\\"))(s) -} - -fn quoted(s: &str) -> IResult<&str, Item> { - terminated(preceded(tag("\""), esc), tag("\""))(s) - .map(|(a, b)| (a, Item::Quoted(b.to_string()))) -} - -fn unquoted(s: &str) -> IResult<&str, Item> { - is_not(" |")(s).map(|(a, b)| (a, Item::Bare(b.to_string()))) -} - -fn operator(s: &str) -> IResult<&str, Item> { - alt(( - tag("=="), - tag("!="), - tag("<"), - tag(">"), - tag("<="), - tag(">="), - ))(s) - .map(|(a, b)| (a, Item::Operator(FromStr::from_str(b).unwrap()))) -} - -fn int(s: &str) -> IResult<&str, Item> { - is_a("1234567890")(s).map(|(a, b)| (a, Item::Int(FromStr::from_str(b).unwrap()))) -} - -fn boolean(s: &str) -> IResult<&str, Item> { - alt((tag("true"), tag("false")))(s) - .map(|(a, b)| (a, Item::Boolean(FromStr::from_str(b).unwrap()))) -} - -fn command_token(s: &str) -> IResult<&str, Item> { - alt((boolean, int, operator, quoted, unquoted))(s) -} - -fn command_args(s: &str) -> IResult<&str, Vec> { - separated_list(tag(" "), command_token)(s) -} - -named!( - pub shell_parser(&str) -> Vec>, - complete!( - ws!( - separated_list!(tag("|"), command_args) - ) - ) -); diff --git a/src/parser/parser.lalrpop b/src/parser/parser.lalrpop new file mode 100644 index 0000000000..05a74c8eb8 --- /dev/null +++ b/src/parser/parser.lalrpop @@ -0,0 +1,56 @@ +use std::str::FromStr; +use crate::parser::tokens::*; + +grammar; + +pub Pipeline: Pipeline = { + => Pipeline::new(vec![first]), + )+> => Pipeline::from_parts(first, rest), +} + +Command: ParsedCommand = { + => ParsedCommand::new(command, expr) +} + +Expr: Expression = { + => Expression::Leaf(<>), + => Expression::Binary(<>), +} + +Operator: Operator = { + "==" => Operator::Equal, + "!=" => Operator::NotEqual, + "<" => Operator::LessThan, + ">" => Operator::GreaterThan, + "<=" => Operator::LessThanOrEqual, + ">=" => Operator::GreaterThanOrEqual +} + +Binary: Binary = { + => Binary::new(left, op, right), +} + +Flag: Flag = { + "-" => Flag::Shorthand(<>.to_string()), + "--" => Flag::Longhand(<>.to_string()), +} + +String: String = { + SQString, + DQString, +} + +Leaf: Leaf = { + => Leaf::String(<>), + => Leaf::Int(<>), + => match <>.as_ref() { + "true" => Leaf::Boolean(true), + "false" => Leaf::Boolean(false), + _ => Leaf::Bare(<>), + } +} + +RawBareWord: String = => <>.to_string(); +DQString: String = => s[1..s.len() - 1].to_string(); +SQString: String = => s[1..s.len() - 1].to_string(); +Num: i64 = => i64::from_str(s).unwrap(); diff --git a/src/parser/parser.rs b/src/parser/parser.rs new file mode 100644 index 0000000000..cec2c99950 --- /dev/null +++ b/src/parser/parser.rs @@ -0,0 +1,2109 @@ +// auto-generated: "lalrpop 0.17.0" +// sha256: 7132ca5588d13f92326a5d97d9b36dd552bef8de12f7ab694b98ba1b169c5 +use std::str::FromStr; +use crate::parser::tokens::*; +#[allow(unused_extern_crates)] +extern crate lalrpop_util as __lalrpop_util; +#[allow(unused_imports)] +use self::__lalrpop_util::state_machine as __state_machine; + +#[cfg_attr(rustfmt, rustfmt_skip)] +mod __parse__Pipeline { + #![allow(non_snake_case, non_camel_case_types, unused_mut, unused_variables, unused_imports, unused_parens)] + + use std::str::FromStr; + use crate::parser::tokens::*; + #[allow(unused_extern_crates)] + extern crate lalrpop_util as __lalrpop_util; + #[allow(unused_imports)] + use self::__lalrpop_util::state_machine as __state_machine; + use super::__intern_token::Token; + #[allow(dead_code)] + pub enum __Symbol<'input> + { + Variant0(&'input str), + Variant1(ParsedCommand), + Variant2(::std::vec::Vec), + Variant3(Binary), + Variant4(String), + Variant5(Expression), + Variant6(::std::vec::Vec), + Variant7(Flag), + Variant8(Leaf), + Variant9(i64), + Variant10(Operator), + Variant11(Pipeline), + } + const __ACTION: &'static [i8] = &[ + // State 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + // State 1 + 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, + // State 2 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 3 + 0, 0, 0, 0, 0, 0, 0, 0, -5, 17, 18, 19, 5, + // State 4 + -28, 0, 0, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + // State 5 + 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, + // State 6 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + // State 7 + 0, 0, 0, 0, 0, 0, 0, 0, -9, -9, -9, -9, -9, + // State 8 + -31, 0, 0, -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, + // State 9 + 0, 0, 0, 0, 0, 0, 0, 0, -12, -12, -12, -12, -12, + // State 10 + 0, 0, 0, 0, 0, 0, 0, 0, -6, 17, 18, 19, 5, + // State 11 + 24, 0, 0, 25, 26, 27, 28, 29, -8, -8, -8, -8, -8, + // State 12 + -17, 0, 0, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, + // State 13 + -18, 0, 0, -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + // State 14 + -30, 0, 0, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + // State 15 + -16, 0, 0, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, + // State 16 + -7, 0, 0, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, + // State 17 + -29, 0, 0, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, + // State 18 + -19, 0, 0, -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, + // State 19 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + // State 20 + 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, + // State 21 + 0, 0, 0, 0, 0, 0, 0, 0, -13, -13, -13, -13, -13, + // State 22 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 5, + // State 23 + 0, 0, 0, 0, 0, 0, 0, 0, 0, -21, -21, -21, -21, + // State 24 + 0, 0, 0, 0, 0, 0, 0, 0, 0, -22, -22, -22, -22, + // State 25 + 0, 0, 0, 0, 0, 0, 0, 0, 0, -24, -24, -24, -24, + // State 26 + 0, 0, 0, 0, 0, 0, 0, 0, 0, -20, -20, -20, -20, + // State 27 + 0, 0, 0, 0, 0, 0, 0, 0, 0, -23, -23, -23, -23, + // State 28 + 0, 0, 0, 0, 0, 0, 0, 0, 0, -25, -25, -25, -25, + // State 29 + 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, + // State 30 + 0, 0, 0, 0, 0, 0, 0, 0, -4, -4, -4, -4, -4, + ]; + const __EOF_ACTION: &'static [i8] = &[ + // State 0 + 0, + // State 1 + -26, + // State 2 + -32, + // State 3 + -5, + // State 4 + -28, + // State 5 + -27, + // State 6 + 0, + // State 7 + -9, + // State 8 + -31, + // State 9 + -12, + // State 10 + -6, + // State 11 + -8, + // State 12 + -17, + // State 13 + -18, + // State 14 + -30, + // State 15 + -16, + // State 16 + -7, + // State 17 + -29, + // State 18 + -19, + // State 19 + 0, + // State 20 + -2, + // State 21 + -13, + // State 22 + 0, + // State 23 + 0, + // State 24 + 0, + // State 25 + 0, + // State 26 + 0, + // State 27 + 0, + // State 28 + 0, + // State 29 + -3, + // State 30 + -4, + ]; + const __GOTO: &'static [i8] = &[ + // State 0 + 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, + // State 1 + 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 2 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 3 + 0, 0, 8, 0, 9, 10, 0, 11, 0, 12, 13, 0, 0, 14, 15, 16, 0, + // State 4 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 5 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 6 + 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + // State 7 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 8 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 9 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 10 + 0, 0, 8, 0, 9, 22, 0, 0, 0, 12, 13, 0, 0, 14, 15, 16, 0, + // State 11 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, + // State 12 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 13 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 14 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 15 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 16 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 17 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 18 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 19 + 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + // State 20 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 21 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 22 + 0, 0, 0, 0, 9, 0, 0, 0, 0, 31, 13, 0, 0, 14, 15, 16, 0, + // State 23 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 24 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 25 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 26 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 27 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 28 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 29 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // State 30 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + fn __expected_tokens(__state: usize) -> Vec<::std::string::String> { + const __TERMINAL: &'static [&'static str] = &[ + r###""!=""###, + r###""-""###, + r###""--""###, + r###""<""###, + r###""<=""###, + r###""==""###, + r###"">""###, + r###"">=""###, + r###""|""###, + r###"r#"\"([^\"]|\\\\\")*\""#"###, + r###"r#"\'([^\']|\\\\\')*\'"#"###, + r###"r#"-?[0-9]+"#"###, + r###"r#"[^0-9\"\'\\-][^\\s]*"#"###, + ]; + __ACTION[(__state * 13)..].iter().zip(__TERMINAL).filter_map(|(&state, terminal)| { + if state == 0 { + None + } else { + Some(terminal.to_string()) + } + }).collect() + } + pub struct __StateMachine<'input> + where + { + input: &'input str, + __phantom: ::std::marker::PhantomData<(&'input ())>, + } + impl<'input> __state_machine::ParserDefinition for __StateMachine<'input> + where + { + type Location = usize; + type Error = &'static str; + type Token = Token<'input>; + type TokenIndex = usize; + type Symbol = __Symbol<'input>; + type Success = Pipeline; + type StateIndex = i8; + type Action = i8; + type ReduceIndex = i8; + type NonterminalIndex = usize; + + #[inline] + fn start_location(&self) -> Self::Location { + Default::default() + } + + #[inline] + fn start_state(&self) -> Self::StateIndex { + 0 + } + + #[inline] + fn token_to_index(&self, token: &Self::Token) -> Option { + __token_to_integer(token, ::std::marker::PhantomData::<(&())>) + } + + #[inline] + fn action(&self, state: i8, integer: usize) -> i8 { + __ACTION[(state as usize) * 13 + integer] + } + + #[inline] + fn error_action(&self, state: i8) -> i8 { + __ACTION[(state as usize) * 13 + (13 - 1)] + } + + #[inline] + fn eof_action(&self, state: i8) -> i8 { + __EOF_ACTION[state as usize] + } + + #[inline] + fn goto(&self, state: i8, nt: usize) -> i8 { + __GOTO[(state as usize) * 17 + nt] - 1 + } + + fn token_to_symbol(&self, token_index: usize, token: Self::Token) -> Self::Symbol { + __token_to_symbol(token_index, token, ::std::marker::PhantomData::<(&())>) + } + + fn expected_tokens(&self, state: i8) -> Vec { + __expected_tokens(state as usize) + } + + #[inline] + fn uses_error_recovery(&self) -> bool { + false + } + + #[inline] + fn error_recovery_symbol( + &self, + recovery: __state_machine::ErrorRecovery, + ) -> Self::Symbol { + panic!("error recovery not enabled for this grammar") + } + + fn reduce( + &mut self, + action: i8, + start_location: Option<&Self::Location>, + states: &mut Vec, + symbols: &mut Vec<__state_machine::SymbolTriple>, + ) -> Option<__state_machine::ParseResult> { + __reduce( + self.input, + action, + start_location, + states, + symbols, + ::std::marker::PhantomData::<(&())>, + ) + } + + fn simulate_reduce(&self, action: i8) -> __state_machine::SimulatedReduce { + __simulate_reduce(action, ::std::marker::PhantomData::<(&())>) + } + } + fn __token_to_integer< + 'input, + >( + __token: &Token<'input>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> Option + { + match *__token { + Token(4, _) if true => Some(0), + Token(5, _) if true => Some(1), + Token(6, _) if true => Some(2), + Token(7, _) if true => Some(3), + Token(8, _) if true => Some(4), + Token(9, _) if true => Some(5), + Token(10, _) if true => Some(6), + Token(11, _) if true => Some(7), + Token(12, _) if true => Some(8), + Token(0, _) if true => Some(9), + Token(1, _) if true => Some(10), + Token(2, _) if true => Some(11), + Token(3, _) if true => Some(12), + _ => None, + } + } + fn __token_to_symbol< + 'input, + >( + __token_index: usize, + __token: Token<'input>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> __Symbol<'input> + { + match __token_index { + 0 => match __token { + Token(4, __tok0) => __Symbol::Variant0((__tok0)), + _ => unreachable!(), + }, + 1 => match __token { + Token(5, __tok0) => __Symbol::Variant0((__tok0)), + _ => unreachable!(), + }, + 2 => match __token { + Token(6, __tok0) => __Symbol::Variant0((__tok0)), + _ => unreachable!(), + }, + 3 => match __token { + Token(7, __tok0) => __Symbol::Variant0((__tok0)), + _ => unreachable!(), + }, + 4 => match __token { + Token(8, __tok0) => __Symbol::Variant0((__tok0)), + _ => unreachable!(), + }, + 5 => match __token { + Token(9, __tok0) => __Symbol::Variant0((__tok0)), + _ => unreachable!(), + }, + 6 => match __token { + Token(10, __tok0) => __Symbol::Variant0((__tok0)), + _ => unreachable!(), + }, + 7 => match __token { + Token(11, __tok0) => __Symbol::Variant0((__tok0)), + _ => unreachable!(), + }, + 8 => match __token { + Token(12, __tok0) => __Symbol::Variant0((__tok0)), + _ => unreachable!(), + }, + 9 => match __token { + Token(0, __tok0) => __Symbol::Variant0((__tok0)), + _ => unreachable!(), + }, + 10 => match __token { + Token(1, __tok0) => __Symbol::Variant0((__tok0)), + _ => unreachable!(), + }, + 11 => match __token { + Token(2, __tok0) => __Symbol::Variant0((__tok0)), + _ => unreachable!(), + }, + 12 => match __token { + Token(3, __tok0) => __Symbol::Variant0((__tok0)), + _ => unreachable!(), + }, + _ => unreachable!(), + } + } + fn __simulate_reduce< + 'input, + >( + __reduce_index: i8, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> __state_machine::SimulatedReduce<__StateMachine<'input>> + { + match __reduce_index { + 0 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 2, + nonterminal_produced: 0, + } + } + 1 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 2, + nonterminal_produced: 1, + } + } + 2 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 3, + nonterminal_produced: 1, + } + } + 3 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 3, + nonterminal_produced: 2, + } + } + 4 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 3, + } + } + 5 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 2, + nonterminal_produced: 3, + } + } + 6 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 4, + } + } + 7 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 5, + } + } + 8 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 5, + } + } + 9 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 0, + nonterminal_produced: 6, + } + } + 10 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 6, + } + } + 11 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 7, + } + } + 12 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 2, + nonterminal_produced: 7, + } + } + 13 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 2, + nonterminal_produced: 8, + } + } + 14 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 2, + nonterminal_produced: 8, + } + } + 15 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 9, + } + } + 16 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 9, + } + } + 17 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 9, + } + } + 18 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 10, + } + } + 19 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 11, + } + } + 20 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 11, + } + } + 21 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 11, + } + } + 22 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 11, + } + } + 23 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 11, + } + } + 24 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 11, + } + } + 25 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 12, + } + } + 26 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 2, + nonterminal_produced: 12, + } + } + 27 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 13, + } + } + 28 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 14, + } + } + 29 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 15, + } + } + 30 => { + __state_machine::SimulatedReduce::Reduce { + states_to_pop: 1, + nonterminal_produced: 15, + } + } + 31 => __state_machine::SimulatedReduce::Accept, + _ => panic!("invalid reduction index {}", __reduce_index) + } + } + pub struct PipelineParser { + builder: super::__intern_token::__MatcherBuilder, + _priv: (), + } + + impl PipelineParser { + pub fn new() -> PipelineParser { + let __builder = super::__intern_token::__MatcherBuilder::new(); + PipelineParser { + builder: __builder, + _priv: (), + } + } + + #[allow(dead_code)] + pub fn parse< + 'input, + >( + &self, + input: &'input str, + ) -> Result, &'static str>> + { + let mut __tokens = self.builder.matcher(input); + let __r = __state_machine::Parser::drive( + __StateMachine { + input, + __phantom: ::std::marker::PhantomData::<(&())>, + }, + __tokens, + ); + __r + } + } + pub(crate) fn __reduce< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> Option, &'static str>>> + { + let (__pop_states, __nonterminal) = match __action { + 0 => { + __reduce0(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 1 => { + __reduce1(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 2 => { + __reduce2(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 3 => { + __reduce3(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 4 => { + __reduce4(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 5 => { + __reduce5(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 6 => { + __reduce6(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 7 => { + __reduce7(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 8 => { + __reduce8(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 9 => { + __reduce9(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 10 => { + __reduce10(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 11 => { + __reduce11(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 12 => { + __reduce12(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 13 => { + __reduce13(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 14 => { + __reduce14(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 15 => { + __reduce15(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 16 => { + __reduce16(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 17 => { + __reduce17(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 18 => { + __reduce18(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 19 => { + __reduce19(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 20 => { + __reduce20(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 21 => { + __reduce21(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 22 => { + __reduce22(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 23 => { + __reduce23(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 24 => { + __reduce24(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 25 => { + __reduce25(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 26 => { + __reduce26(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 27 => { + __reduce27(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 28 => { + __reduce28(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 29 => { + __reduce29(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 30 => { + __reduce30(input, __action, __lookahead_start, __states, __symbols, ::std::marker::PhantomData::<(&())>) + } + 31 => { + // __Pipeline = Pipeline => ActionFn(0); + let __sym0 = __pop_Variant11(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action0::<>(input, __sym0); + return Some(Ok(__nt)); + } + _ => panic!("invalid action code {}", __action) + }; + let __states_len = __states.len(); + __states.truncate(__states_len - __pop_states); + let __state = *__states.last().unwrap() as usize; + let __next_state = __GOTO[__state * 17 + __nonterminal] - 1; + __states.push(__next_state); + None + } + fn __pop_Variant3< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, Binary, usize) + { + match __symbols.pop().unwrap() { + (__l, __Symbol::Variant3(__v), __r) => (__l, __v, __r), + _ => panic!("symbol type mismatch") + } + } + fn __pop_Variant5< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, Expression, usize) + { + match __symbols.pop().unwrap() { + (__l, __Symbol::Variant5(__v), __r) => (__l, __v, __r), + _ => panic!("symbol type mismatch") + } + } + fn __pop_Variant7< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, Flag, usize) + { + match __symbols.pop().unwrap() { + (__l, __Symbol::Variant7(__v), __r) => (__l, __v, __r), + _ => panic!("symbol type mismatch") + } + } + fn __pop_Variant8< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, Leaf, usize) + { + match __symbols.pop().unwrap() { + (__l, __Symbol::Variant8(__v), __r) => (__l, __v, __r), + _ => panic!("symbol type mismatch") + } + } + fn __pop_Variant10< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, Operator, usize) + { + match __symbols.pop().unwrap() { + (__l, __Symbol::Variant10(__v), __r) => (__l, __v, __r), + _ => panic!("symbol type mismatch") + } + } + fn __pop_Variant1< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, ParsedCommand, usize) + { + match __symbols.pop().unwrap() { + (__l, __Symbol::Variant1(__v), __r) => (__l, __v, __r), + _ => panic!("symbol type mismatch") + } + } + fn __pop_Variant11< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, Pipeline, usize) + { + match __symbols.pop().unwrap() { + (__l, __Symbol::Variant11(__v), __r) => (__l, __v, __r), + _ => panic!("symbol type mismatch") + } + } + fn __pop_Variant4< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, String, usize) + { + match __symbols.pop().unwrap() { + (__l, __Symbol::Variant4(__v), __r) => (__l, __v, __r), + _ => panic!("symbol type mismatch") + } + } + fn __pop_Variant9< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, i64, usize) + { + match __symbols.pop().unwrap() { + (__l, __Symbol::Variant9(__v), __r) => (__l, __v, __r), + _ => panic!("symbol type mismatch") + } + } + fn __pop_Variant6< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, ::std::vec::Vec, usize) + { + match __symbols.pop().unwrap() { + (__l, __Symbol::Variant6(__v), __r) => (__l, __v, __r), + _ => panic!("symbol type mismatch") + } + } + fn __pop_Variant2< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, ::std::vec::Vec, usize) + { + match __symbols.pop().unwrap() { + (__l, __Symbol::Variant2(__v), __r) => (__l, __v, __r), + _ => panic!("symbol type mismatch") + } + } + fn __pop_Variant0< + 'input, + >( + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, &'input str, usize) + { + match __symbols.pop().unwrap() { + (__l, __Symbol::Variant0(__v), __r) => (__l, __v, __r), + _ => panic!("symbol type mismatch") + } + } + pub(crate) fn __reduce0< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // ("|" ) = "|", Command => ActionFn(28); + let __sym1 = __pop_Variant1(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym1.2.clone(); + let __nt = super::__action28::<>(input, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant1(__nt), __end)); + (2, 0) + } + pub(crate) fn __reduce1< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // ("|" )+ = "|", Command => ActionFn(31); + let __sym1 = __pop_Variant1(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym1.2.clone(); + let __nt = super::__action31::<>(input, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant2(__nt), __end)); + (2, 1) + } + pub(crate) fn __reduce2< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // ("|" )+ = ("|" )+, "|", Command => ActionFn(32); + let __sym2 = __pop_Variant1(__symbols); + let __sym1 = __pop_Variant0(__symbols); + let __sym0 = __pop_Variant2(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym2.2.clone(); + let __nt = super::__action32::<>(input, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant2(__nt), __end)); + (3, 1) + } + pub(crate) fn __reduce3< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Binary = Leaf, Operator, Leaf => ActionFn(12); + let __sym2 = __pop_Variant8(__symbols); + let __sym1 = __pop_Variant10(__symbols); + let __sym0 = __pop_Variant8(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym2.2.clone(); + let __nt = super::__action12::<>(input, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant3(__nt), __end)); + (3, 2) + } + pub(crate) fn __reduce4< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Command = RawBareWord => ActionFn(33); + let __sym0 = __pop_Variant4(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action33::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant1(__nt), __end)); + (1, 3) + } + pub(crate) fn __reduce5< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Command = RawBareWord, Expr+ => ActionFn(34); + let __sym1 = __pop_Variant6(__symbols); + let __sym0 = __pop_Variant4(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym1.2.clone(); + let __nt = super::__action34::<>(input, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant1(__nt), __end)); + (2, 3) + } + pub(crate) fn __reduce6< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // DQString = r#"\"([^\"]|\\\\\")*\""# => ActionFn(21); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action21::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant4(__nt), __end)); + (1, 4) + } + pub(crate) fn __reduce7< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Expr = Leaf => ActionFn(4); + let __sym0 = __pop_Variant8(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action4::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant5(__nt), __end)); + (1, 5) + } + pub(crate) fn __reduce8< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Expr = Binary => ActionFn(5); + let __sym0 = __pop_Variant3(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action5::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant5(__nt), __end)); + (1, 5) + } + pub(crate) fn __reduce9< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Expr* = => ActionFn(24); + let __start = __symbols.last().map(|s| s.2.clone()).unwrap_or_default(); + let __end = __lookahead_start.cloned().unwrap_or_else(|| __start.clone()); + let __nt = super::__action24::<>(input, &__start, &__end); + __symbols.push((__start, __Symbol::Variant6(__nt), __end)); + (0, 6) + } + pub(crate) fn __reduce10< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Expr* = Expr+ => ActionFn(25); + let __sym0 = __pop_Variant6(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action25::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant6(__nt), __end)); + (1, 6) + } + pub(crate) fn __reduce11< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Expr+ = Expr => ActionFn(29); + let __sym0 = __pop_Variant5(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action29::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant6(__nt), __end)); + (1, 7) + } + pub(crate) fn __reduce12< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Expr+ = Expr+, Expr => ActionFn(30); + let __sym1 = __pop_Variant5(__symbols); + let __sym0 = __pop_Variant6(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym1.2.clone(); + let __nt = super::__action30::<>(input, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant6(__nt), __end)); + (2, 7) + } + pub(crate) fn __reduce13< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Flag = "-", RawBareWord => ActionFn(13); + let __sym1 = __pop_Variant4(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym1.2.clone(); + let __nt = super::__action13::<>(input, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant7(__nt), __end)); + (2, 8) + } + pub(crate) fn __reduce14< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Flag = "--", RawBareWord => ActionFn(14); + let __sym1 = __pop_Variant4(__symbols); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym1.2.clone(); + let __nt = super::__action14::<>(input, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant7(__nt), __end)); + (2, 8) + } + pub(crate) fn __reduce15< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Leaf = String => ActionFn(17); + let __sym0 = __pop_Variant4(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action17::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant8(__nt), __end)); + (1, 9) + } + pub(crate) fn __reduce16< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Leaf = Num => ActionFn(18); + let __sym0 = __pop_Variant9(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action18::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant8(__nt), __end)); + (1, 9) + } + pub(crate) fn __reduce17< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Leaf = RawBareWord => ActionFn(19); + let __sym0 = __pop_Variant4(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action19::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant8(__nt), __end)); + (1, 9) + } + pub(crate) fn __reduce18< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Num = r#"-?[0-9]+"# => ActionFn(23); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action23::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant9(__nt), __end)); + (1, 10) + } + pub(crate) fn __reduce19< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Operator = "==" => ActionFn(6); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action6::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant10(__nt), __end)); + (1, 11) + } + pub(crate) fn __reduce20< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Operator = "!=" => ActionFn(7); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action7::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant10(__nt), __end)); + (1, 11) + } + pub(crate) fn __reduce21< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Operator = "<" => ActionFn(8); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action8::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant10(__nt), __end)); + (1, 11) + } + pub(crate) fn __reduce22< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Operator = ">" => ActionFn(9); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action9::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant10(__nt), __end)); + (1, 11) + } + pub(crate) fn __reduce23< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Operator = "<=" => ActionFn(10); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action10::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant10(__nt), __end)); + (1, 11) + } + pub(crate) fn __reduce24< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Operator = ">=" => ActionFn(11); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action11::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant10(__nt), __end)); + (1, 11) + } + pub(crate) fn __reduce25< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Pipeline = Command => ActionFn(1); + let __sym0 = __pop_Variant1(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action1::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant11(__nt), __end)); + (1, 12) + } + pub(crate) fn __reduce26< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // Pipeline = Command, ("|" )+ => ActionFn(2); + let __sym1 = __pop_Variant2(__symbols); + let __sym0 = __pop_Variant1(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym1.2.clone(); + let __nt = super::__action2::<>(input, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant11(__nt), __end)); + (2, 12) + } + pub(crate) fn __reduce27< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // RawBareWord = r#"[^0-9\"\'\\-][^\\s]*"# => ActionFn(20); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action20::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant4(__nt), __end)); + (1, 13) + } + pub(crate) fn __reduce28< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // SQString = r#"\'([^\']|\\\\\')*\'"# => ActionFn(22); + let __sym0 = __pop_Variant0(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action22::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant4(__nt), __end)); + (1, 14) + } + pub(crate) fn __reduce29< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // String = SQString => ActionFn(15); + let __sym0 = __pop_Variant4(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action15::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant4(__nt), __end)); + (1, 15) + } + pub(crate) fn __reduce30< + 'input, + >( + input: &'input str, + __action: i8, + __lookahead_start: Option<&usize>, + __states: &mut ::std::vec::Vec, + __symbols: &mut ::std::vec::Vec<(usize,__Symbol<'input>,usize)>, + _: ::std::marker::PhantomData<(&'input ())>, + ) -> (usize, usize) + { + // String = DQString => ActionFn(16); + let __sym0 = __pop_Variant4(__symbols); + let __start = __sym0.0.clone(); + let __end = __sym0.2.clone(); + let __nt = super::__action16::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant4(__nt), __end)); + (1, 15) + } +} +pub use self::__parse__Pipeline::PipelineParser; +#[cfg_attr(rustfmt, rustfmt_skip)] +mod __intern_token { + #![allow(unused_imports)] + use std::str::FromStr; + use crate::parser::tokens::*; + #[allow(unused_extern_crates)] + extern crate lalrpop_util as __lalrpop_util; + #[allow(unused_imports)] + use self::__lalrpop_util::state_machine as __state_machine; + extern crate regex as __regex; + use std::fmt as __fmt; + + #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] + pub struct Token<'input>(pub usize, pub &'input str); + impl<'a> __fmt::Display for Token<'a> { + fn fmt<'f>(&self, formatter: &mut __fmt::Formatter<'f>) -> Result<(), __fmt::Error> { + __fmt::Display::fmt(self.1, formatter) + } + } + + pub struct __MatcherBuilder { + regex_set: __regex::RegexSet, + regex_vec: Vec<__regex::Regex>, + } + + impl __MatcherBuilder { + pub fn new() -> __MatcherBuilder { + let __strs: &[&str] = &[ + "^(\"([\u{0}-!\\#-\u{10ffff}]|\\\\\")*\")", + "^(\'([\u{0}-\\&\\(-\u{10ffff}]|\\\\\')*\')", + "^(\\-?[0-9]+)", + "^([\u{0}-!\\#-\\&\\(-,\\.-/:-\u{10ffff}][\u{0}-\u{8}\u{e}-\u{1f}!-\u{84}\u{86}-\u{9f}¡-ᙿᚁ-\u{1fff}\u{200b}-‧\u{202a}-\u{202e}‰-⁞\u{2060}-\u{2fff}、-\u{10ffff}]*)", + "^(!=)", + "^(\\-)", + "^(\\-\\-)", + "^(<)", + "^(<=)", + "^(==)", + "^(>)", + "^(>=)", + "^(\\|)", + ]; + let __regex_set = __regex::RegexSet::new(__strs).unwrap(); + let __regex_vec = vec![ + __regex::Regex::new("^(\"([\u{0}-!\\#-\u{10ffff}]|\\\\\")*\")").unwrap(), + __regex::Regex::new("^(\'([\u{0}-\\&\\(-\u{10ffff}]|\\\\\')*\')").unwrap(), + __regex::Regex::new("^(\\-?[0-9]+)").unwrap(), + __regex::Regex::new("^([\u{0}-!\\#-\\&\\(-,\\.-/:-\u{10ffff}][\u{0}-\u{8}\u{e}-\u{1f}!-\u{84}\u{86}-\u{9f}¡-ᙿᚁ-\u{1fff}\u{200b}-‧\u{202a}-\u{202e}‰-⁞\u{2060}-\u{2fff}、-\u{10ffff}]*)").unwrap(), + __regex::Regex::new("^(!=)").unwrap(), + __regex::Regex::new("^(\\-)").unwrap(), + __regex::Regex::new("^(\\-\\-)").unwrap(), + __regex::Regex::new("^(<)").unwrap(), + __regex::Regex::new("^(<=)").unwrap(), + __regex::Regex::new("^(==)").unwrap(), + __regex::Regex::new("^(>)").unwrap(), + __regex::Regex::new("^(>=)").unwrap(), + __regex::Regex::new("^(\\|)").unwrap(), + ]; + __MatcherBuilder { regex_set: __regex_set, regex_vec: __regex_vec } + } + pub fn matcher<'input, 'builder>(&'builder self, s: &'input str) -> __Matcher<'input, 'builder> { + __Matcher { + text: s, + consumed: 0, + regex_set: &self.regex_set, + regex_vec: &self.regex_vec, + } + } + } + + pub struct __Matcher<'input, 'builder> { + text: &'input str, + consumed: usize, + regex_set: &'builder __regex::RegexSet, + regex_vec: &'builder Vec<__regex::Regex>, + } + + impl<'input, 'builder> Iterator for __Matcher<'input, 'builder> { + type Item = Result<(usize, Token<'input>, usize), __lalrpop_util::ParseError,&'static str>>; + + fn next(&mut self) -> Option { + let __text = self.text.trim_start(); + let __whitespace = self.text.len() - __text.len(); + let __start_offset = self.consumed + __whitespace; + if __text.is_empty() { + self.text = __text; + self.consumed = __start_offset; + None + } else { + let __matches = self.regex_set.matches(__text); + if !__matches.matched_any() { + Some(Err(__lalrpop_util::ParseError::InvalidToken { + location: __start_offset, + })) + } else { + let mut __longest_match = 0; + let mut __index = 0; + for __i in 0 .. 13 { + if __matches.matched(__i) { + let __match = self.regex_vec[__i].find(__text).unwrap(); + let __len = __match.end(); + if __len >= __longest_match { + __longest_match = __len; + __index = __i; + } + } + } + let __result = &__text[..__longest_match]; + let __remaining = &__text[__longest_match..]; + let __end_offset = __start_offset + __longest_match; + self.text = __remaining; + self.consumed = __end_offset; + Some(Ok((__start_offset, Token(__index, __result), __end_offset))) + } + } + } + } +} +pub use self::__intern_token::Token; + +#[allow(unused_variables)] +fn __action0< + 'input, +>( + input: &'input str, + (_, __0, _): (usize, Pipeline, usize), +) -> Pipeline +{ + (__0) +} + +#[allow(unused_variables)] +fn __action1< + 'input, +>( + input: &'input str, + (_, first, _): (usize, ParsedCommand, usize), +) -> Pipeline +{ + Pipeline::new(vec![first]) +} + +#[allow(unused_variables)] +fn __action2< + 'input, +>( + input: &'input str, + (_, first, _): (usize, ParsedCommand, usize), + (_, rest, _): (usize, ::std::vec::Vec, usize), +) -> Pipeline +{ + Pipeline::from_parts(first, rest) +} + +#[allow(unused_variables)] +fn __action3< + 'input, +>( + input: &'input str, + (_, command, _): (usize, String, usize), + (_, expr, _): (usize, ::std::vec::Vec, usize), +) -> ParsedCommand +{ + ParsedCommand::new(command, expr) +} + +#[allow(unused_variables)] +fn __action4< + 'input, +>( + input: &'input str, + (_, __0, _): (usize, Leaf, usize), +) -> Expression +{ + Expression::Leaf(__0) +} + +#[allow(unused_variables)] +fn __action5< + 'input, +>( + input: &'input str, + (_, __0, _): (usize, Binary, usize), +) -> Expression +{ + Expression::Binary(__0) +} + +#[allow(unused_variables)] +fn __action6< + 'input, +>( + input: &'input str, + (_, __0, _): (usize, &'input str, usize), +) -> Operator +{ + Operator::Equal +} + +#[allow(unused_variables)] +fn __action7< + 'input, +>( + input: &'input str, + (_, __0, _): (usize, &'input str, usize), +) -> Operator +{ + Operator::NotEqual +} + +#[allow(unused_variables)] +fn __action8< + 'input, +>( + input: &'input str, + (_, __0, _): (usize, &'input str, usize), +) -> Operator +{ + Operator::LessThan +} + +#[allow(unused_variables)] +fn __action9< + 'input, +>( + input: &'input str, + (_, __0, _): (usize, &'input str, usize), +) -> Operator +{ + Operator::GreaterThan +} + +#[allow(unused_variables)] +fn __action10< + 'input, +>( + input: &'input str, + (_, __0, _): (usize, &'input str, usize), +) -> Operator +{ + Operator::LessThanOrEqual +} + +#[allow(unused_variables)] +fn __action11< + 'input, +>( + input: &'input str, + (_, __0, _): (usize, &'input str, usize), +) -> Operator +{ + Operator::GreaterThanOrEqual +} + +#[allow(unused_variables)] +fn __action12< + 'input, +>( + input: &'input str, + (_, left, _): (usize, Leaf, usize), + (_, op, _): (usize, Operator, usize), + (_, right, _): (usize, Leaf, usize), +) -> Binary +{ + Binary::new(left, op, right) +} + +#[allow(unused_variables)] +fn __action13< + 'input, +>( + input: &'input str, + (_, _, _): (usize, &'input str, usize), + (_, __0, _): (usize, String, usize), +) -> Flag +{ + Flag::Shorthand(__0.to_string()) +} + +#[allow(unused_variables)] +fn __action14< + 'input, +>( + input: &'input str, + (_, _, _): (usize, &'input str, usize), + (_, __0, _): (usize, String, usize), +) -> Flag +{ + Flag::Longhand(__0.to_string()) +} + +#[allow(unused_variables)] +fn __action15< + 'input, +>( + input: &'input str, + (_, __0, _): (usize, String, usize), +) -> String +{ + (__0) +} + +#[allow(unused_variables)] +fn __action16< + 'input, +>( + input: &'input str, + (_, __0, _): (usize, String, usize), +) -> String +{ + (__0) +} + +#[allow(unused_variables)] +fn __action17< + 'input, +>( + input: &'input str, + (_, __0, _): (usize, String, usize), +) -> Leaf +{ + Leaf::String(__0) +} + +#[allow(unused_variables)] +fn __action18< + 'input, +>( + input: &'input str, + (_, __0, _): (usize, i64, usize), +) -> Leaf +{ + Leaf::Int(__0) +} + +#[allow(unused_variables)] +fn __action19< + 'input, +>( + input: &'input str, + (_, __0, _): (usize, String, usize), +) -> Leaf +{ + match __0.as_ref() { + "true" => Leaf::Boolean(true), + "false" => Leaf::Boolean(false), + _ => Leaf::Bare(__0), + } +} + +#[allow(unused_variables)] +fn __action20< + 'input, +>( + input: &'input str, + (_, s, _): (usize, &'input str, usize), +) -> String +{ + s.to_string() +} + +#[allow(unused_variables)] +fn __action21< + 'input, +>( + input: &'input str, + (_, s, _): (usize, &'input str, usize), +) -> String +{ + s[1..s.len() - 1].to_string() +} + +#[allow(unused_variables)] +fn __action22< + 'input, +>( + input: &'input str, + (_, s, _): (usize, &'input str, usize), +) -> String +{ + s[1..s.len() - 1].to_string() +} + +#[allow(unused_variables)] +fn __action23< + 'input, +>( + input: &'input str, + (_, s, _): (usize, &'input str, usize), +) -> i64 +{ + i64::from_str(s).unwrap() +} + +#[allow(unused_variables)] +fn __action24< + 'input, +>( + input: &'input str, + __lookbehind: &usize, + __lookahead: &usize, +) -> ::std::vec::Vec +{ + vec![] +} + +#[allow(unused_variables)] +fn __action25< + 'input, +>( + input: &'input str, + (_, v, _): (usize, ::std::vec::Vec, usize), +) -> ::std::vec::Vec +{ + v +} + +#[allow(unused_variables)] +fn __action26< + 'input, +>( + input: &'input str, + (_, __0, _): (usize, ParsedCommand, usize), +) -> ::std::vec::Vec +{ + vec![__0] +} + +#[allow(unused_variables)] +fn __action27< + 'input, +>( + input: &'input str, + (_, v, _): (usize, ::std::vec::Vec, usize), + (_, e, _): (usize, ParsedCommand, usize), +) -> ::std::vec::Vec +{ + { let mut v = v; v.push(e); v } +} + +#[allow(unused_variables)] +fn __action28< + 'input, +>( + input: &'input str, + (_, _, _): (usize, &'input str, usize), + (_, __0, _): (usize, ParsedCommand, usize), +) -> ParsedCommand +{ + (__0) +} + +#[allow(unused_variables)] +fn __action29< + 'input, +>( + input: &'input str, + (_, __0, _): (usize, Expression, usize), +) -> ::std::vec::Vec +{ + vec![__0] +} + +#[allow(unused_variables)] +fn __action30< + 'input, +>( + input: &'input str, + (_, v, _): (usize, ::std::vec::Vec, usize), + (_, e, _): (usize, Expression, usize), +) -> ::std::vec::Vec +{ + { let mut v = v; v.push(e); v } +} + +#[allow(unused_variables)] +fn __action31< + 'input, +>( + input: &'input str, + __0: (usize, &'input str, usize), + __1: (usize, ParsedCommand, usize), +) -> ::std::vec::Vec +{ + let __start0 = __0.0.clone(); + let __end0 = __1.2.clone(); + let __temp0 = __action28( + input, + __0, + __1, + ); + let __temp0 = (__start0, __temp0, __end0); + __action26( + input, + __temp0, + ) +} + +#[allow(unused_variables)] +fn __action32< + 'input, +>( + input: &'input str, + __0: (usize, ::std::vec::Vec, usize), + __1: (usize, &'input str, usize), + __2: (usize, ParsedCommand, usize), +) -> ::std::vec::Vec +{ + let __start0 = __1.0.clone(); + let __end0 = __2.2.clone(); + let __temp0 = __action28( + input, + __1, + __2, + ); + let __temp0 = (__start0, __temp0, __end0); + __action27( + input, + __0, + __temp0, + ) +} + +#[allow(unused_variables)] +fn __action33< + 'input, +>( + input: &'input str, + __0: (usize, String, usize), +) -> ParsedCommand +{ + let __start0 = __0.2.clone(); + let __end0 = __0.2.clone(); + let __temp0 = __action24( + input, + &__start0, + &__end0, + ); + let __temp0 = (__start0, __temp0, __end0); + __action3( + input, + __0, + __temp0, + ) +} + +#[allow(unused_variables)] +fn __action34< + 'input, +>( + input: &'input str, + __0: (usize, String, usize), + __1: (usize, ::std::vec::Vec, usize), +) -> ParsedCommand +{ + let __start0 = __1.0.clone(); + let __end0 = __1.2.clone(); + let __temp0 = __action25( + input, + __1, + ); + let __temp0 = (__start0, __temp0, __end0); + __action3( + input, + __0, + __temp0, + ) +} + +pub trait __ToTriple<'input, > { + fn to_triple(value: Self) -> Result<(usize,Token<'input>,usize), __lalrpop_util::ParseError, &'static str>>; +} + +impl<'input, > __ToTriple<'input, > for (usize, Token<'input>, usize) { + fn to_triple(value: Self) -> Result<(usize,Token<'input>,usize), __lalrpop_util::ParseError, &'static str>> { + Ok(value) + } +} +impl<'input, > __ToTriple<'input, > for Result<(usize, Token<'input>, usize), &'static str> { + fn to_triple(value: Self) -> Result<(usize,Token<'input>,usize), __lalrpop_util::ParseError, &'static str>> { + match value { + Ok(v) => Ok(v), + Err(error) => Err(__lalrpop_util::ParseError::User { error }), + } + } +} diff --git a/src/parser/registry.rs b/src/parser/registry.rs new file mode 100644 index 0000000000..780ea5b939 --- /dev/null +++ b/src/parser/registry.rs @@ -0,0 +1,21 @@ +use indexmap::IndexMap; + +#[allow(unused)] +pub enum CommandType { + Switch, + Single, + Array, +} + +#[allow(unused)] +pub struct CommandConfig { + crate name: String, + crate mandatory_positional: Vec, + crate optional_positional: Vec, + crate rest_positional: bool, + crate named: IndexMap, +} + +pub trait CommandRegistry { + fn get(&self, name: &str) -> CommandConfig; +} diff --git a/src/parser/tokens.rs b/src/parser/tokens.rs new file mode 100644 index 0000000000..51f9c15167 --- /dev/null +++ b/src/parser/tokens.rs @@ -0,0 +1,128 @@ +use derive_new::new; +use std::str::FromStr; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub enum Operator { + Equal, + NotEqual, + LessThan, + GreaterThan, + LessThanOrEqual, + GreaterThanOrEqual, +} + +impl Operator { + pub fn print(&self) -> String { + match *self { + Operator::Equal => "==".to_string(), + Operator::NotEqual => "!=".to_string(), + Operator::LessThan => "<".to_string(), + Operator::GreaterThan => ">".to_string(), + Operator::LessThanOrEqual => "<=".to_string(), + Operator::GreaterThanOrEqual => ">=".to_string(), + } + } +} + +impl FromStr for Operator { + type Err = (); + fn from_str(input: &str) -> Result::Err> { + match input { + "==" => Ok(Operator::Equal), + "!=" => Ok(Operator::NotEqual), + "<" => Ok(Operator::LessThan), + ">" => Ok(Operator::GreaterThan), + "<=" => Ok(Operator::LessThanOrEqual), + ">=" => Ok(Operator::GreaterThanOrEqual), + _ => Err(()), + } + } +} + +#[derive(Debug, Clone)] +pub enum Expression { + Leaf(Leaf), + Binary(Binary), +} + +impl Expression { + crate fn print(&self) -> String { + match self { + Expression::Leaf(l) => l.print(), + Expression::Binary(b) => b.print(), + } + } +} + +#[derive(Debug, Clone)] +pub enum Leaf { + String(String), + Bare(String), + Boolean(bool), + Int(i64), +} + +impl Leaf { + fn print(&self) -> String { + match self { + Leaf::String(s) => format!("{:?}", s), + Leaf::Bare(s) => format!("{}", s), + Leaf::Boolean(b) => format!("{}", b), + Leaf::Int(i) => format!("{}", i), + } + } +} + +#[derive(Debug, Clone, new)] +pub struct Binary { + crate left: Leaf, + crate operator: Operator, + crate right: Leaf, +} + +impl Binary { + fn print(&self) -> String { + format!( + "{} {} {}", + self.left.print(), + self.operator.print(), + self.right.print() + ) + } +} + +#[derive(Debug, Clone)] +pub enum Flag { + Shorthand(String), + Longhand(String), +} + +impl Flag { + #[allow(unused)] + fn print(&self) -> String { + match self { + Flag::Shorthand(s) => format!("-{}", s), + Flag::Longhand(s) => format!("--{}", s), + } + } +} + +#[derive(new, Debug, Clone)] +pub struct ParsedCommand { + crate name: String, + crate args: Vec, +} + +#[derive(new, Debug)] +pub struct Pipeline { + crate commands: Vec, +} + +impl Pipeline { + crate fn from_parts(command: ParsedCommand, rest: Vec) -> Pipeline { + let mut commands = vec![command]; + commands.extend(rest); + + Pipeline { commands } + } +} diff --git a/src/prelude.rs b/src/prelude.rs index 120b74f74b..6bf2e9520f 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -4,7 +4,7 @@ crate use crate::context::Context; crate use crate::env::host::handle_unexpected; crate use crate::env::{Environment, Host}; crate use crate::errors::ShellError; -crate use crate::object::{Primitive, Value}; +crate use crate::object::Value; crate use crate::stream::{single_output, InputStream, OutputStream}; crate use futures::{FutureExt, SinkExt, StreamExt}; crate use std::collections::VecDeque; diff --git a/src/shell/completer.rs b/src/shell/completer.rs index f3912ca672..2099f52700 100644 --- a/src/shell/completer.rs +++ b/src/shell/completer.rs @@ -1,9 +1,13 @@ +use crate::prelude::*; +use derive_new::new; use rustyline::completion::Completer; use rustyline::completion::{self, FilenameCompleter}; use rustyline::line_buffer::LineBuffer; +#[derive(new)] crate struct NuCompleter { pub file_completer: FilenameCompleter, + pub commands: indexmap::IndexMap>, } impl Completer for NuCompleter { @@ -15,10 +19,7 @@ impl Completer for NuCompleter { pos: usize, context: &rustyline::Context, ) -> rustyline::Result<(usize, Vec)> { - let commands = [ - "ps", "ls", "cd", "view", "skip", "take", "select", "reject", "to-array", "where", - "sort-by", - ]; + let commands: Vec = self.commands.keys().cloned().collect(); let mut completions = self.file_completer.complete(line, pos, context)?.1; diff --git a/src/shell/helper.rs b/src/shell/helper.rs index 287c5e5b86..23fe3435eb 100644 --- a/src/shell/helper.rs +++ b/src/shell/helper.rs @@ -1,5 +1,6 @@ use crate::shell::completer::NuCompleter; +use crate::prelude::*; use rustyline::completion::{self, Completer, FilenameCompleter}; use rustyline::error::ReadlineError; use rustyline::highlight::{Highlighter, MatchingBracketHighlighter}; @@ -13,10 +14,11 @@ crate struct Helper { } impl Helper { - crate fn new() -> Helper { + crate fn new(commands: indexmap::IndexMap>) -> Helper { Helper { completer: NuCompleter { file_completer: FilenameCompleter::new(), + commands, }, highlighter: MatchingBracketHighlighter::new(), hinter: HistoryHinter {},