Refactor: remove duplication to simplify lite_parsing logic. (#10735)

When looking into `lite_parse` function, I found that it contains some
duplicate code, and they can be expressed as an action called
`push_command_to(pipeline)`.

And I believe it will make our life easier to support something like
`o>> a.txt`, `e>> a.txt`.
This commit is contained in:
WindSoilder 2023-10-19 05:24:40 +08:00 committed by GitHub
parent 9e7f84afb0
commit d204defb68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -235,74 +235,27 @@ pub fn lite_parse(tokens: &[Token]) -> (LiteBlock, Option<ParseError>) {
TokenContents::OutGreaterThan TokenContents::OutGreaterThan
| TokenContents::ErrGreaterThan | TokenContents::ErrGreaterThan
| TokenContents::OutErrGreaterThan => { | TokenContents::OutErrGreaterThan => {
if !curr_command.is_empty() { push_command_to(
match last_connector { &mut curr_pipeline,
TokenContents::OutGreaterThan => { curr_command,
curr_pipeline.push(LiteElement::Redirection( last_connector,
last_connector_span last_connector_span,
.expect("internal error: redirection missing span information"), );
Redirection::Stdout,
curr_command, curr_command = LiteCommand::new();
));
}
TokenContents::ErrGreaterThan => {
curr_pipeline.push(LiteElement::Redirection(
last_connector_span
.expect("internal error: redirection missing span information"),
Redirection::Stderr,
curr_command,
));
}
TokenContents::OutErrGreaterThan => {
curr_pipeline.push(LiteElement::Redirection(
last_connector_span
.expect("internal error: redirection missing span information"),
Redirection::StdoutAndStderr,
curr_command,
));
}
_ => {
curr_pipeline
.push(LiteElement::Command(last_connector_span, curr_command));
}
}
curr_command = LiteCommand::new();
}
last_token = token.contents; last_token = token.contents;
last_connector = token.contents; last_connector = token.contents;
last_connector_span = Some(token.span); last_connector_span = Some(token.span);
} }
TokenContents::Pipe => { TokenContents::Pipe => {
if !curr_command.is_empty() { push_command_to(
match last_connector { &mut curr_pipeline,
TokenContents::OutGreaterThan => { curr_command,
curr_pipeline.push(LiteElement::Redirection( last_connector,
token.span, last_connector_span,
Redirection::Stdout, );
curr_command,
)); curr_command = LiteCommand::new();
}
TokenContents::ErrGreaterThan => {
curr_pipeline.push(LiteElement::Redirection(
token.span,
Redirection::Stderr,
curr_command,
));
}
TokenContents::OutErrGreaterThan => {
curr_pipeline.push(LiteElement::Redirection(
token.span,
Redirection::StdoutAndStderr,
curr_command,
));
}
_ => {
curr_pipeline
.push(LiteElement::Command(last_connector_span, curr_command));
}
}
curr_command = LiteCommand::new();
}
last_token = TokenContents::Pipe; last_token = TokenContents::Pipe;
last_connector = TokenContents::Pipe; last_connector = TokenContents::Pipe;
last_connector_span = Some(token.span); last_connector_span = Some(token.span);
@ -316,44 +269,14 @@ pub fn lite_parse(tokens: &[Token]) -> (LiteBlock, Option<ParseError>) {
if actual_token != Some(TokenContents::Pipe) if actual_token != Some(TokenContents::Pipe)
&& actual_token != Some(TokenContents::OutGreaterThan) && actual_token != Some(TokenContents::OutGreaterThan)
{ {
if !curr_command.is_empty() { push_command_to(
match last_connector { &mut curr_pipeline,
TokenContents::OutGreaterThan => { curr_command,
curr_pipeline.push(LiteElement::Redirection( last_connector,
last_connector_span.expect( last_connector_span,
"internal error: redirection missing span information", );
),
Redirection::Stdout,
curr_command,
));
}
TokenContents::ErrGreaterThan => {
curr_pipeline.push(LiteElement::Redirection(
last_connector_span.expect(
"internal error: redirection missing span information",
),
Redirection::Stderr,
curr_command,
));
}
TokenContents::OutErrGreaterThan => {
curr_pipeline.push(LiteElement::Redirection(
last_connector_span.expect(
"internal error: redirection missing span information",
),
Redirection::StdoutAndStderr,
curr_command,
));
}
_ => {
curr_pipeline
.push(LiteElement::Command(last_connector_span, curr_command));
}
}
curr_command = LiteCommand::new();
}
curr_command = LiteCommand::new();
if !curr_pipeline.is_empty() { if !curr_pipeline.is_empty() {
block.push(curr_pipeline); block.push(curr_pipeline);
@ -371,41 +294,14 @@ pub fn lite_parse(tokens: &[Token]) -> (LiteBlock, Option<ParseError>) {
last_token = TokenContents::Eol; last_token = TokenContents::Eol;
} }
TokenContents::Semicolon => { TokenContents::Semicolon => {
if !curr_command.is_empty() { push_command_to(
match last_connector { &mut curr_pipeline,
TokenContents::OutGreaterThan => { curr_command,
curr_pipeline.push(LiteElement::Redirection( last_connector,
last_connector_span last_connector_span,
.expect("internal error: redirection missing span information"), );
Redirection::Stdout,
curr_command,
));
}
TokenContents::ErrGreaterThan => {
curr_pipeline.push(LiteElement::Redirection(
last_connector_span
.expect("internal error: redirection missing span information"),
Redirection::Stderr,
curr_command,
));
}
TokenContents::OutErrGreaterThan => {
curr_pipeline.push(LiteElement::Redirection(
last_connector_span
.expect("internal error: redirection missing span information"),
Redirection::StdoutAndStderr,
curr_command,
));
}
_ => {
curr_pipeline
.push(LiteElement::Command(last_connector_span, curr_command));
}
}
curr_command = LiteCommand::new();
}
curr_command = LiteCommand::new();
if !curr_pipeline.is_empty() { if !curr_pipeline.is_empty() {
block.push(curr_pipeline); block.push(curr_pipeline);
@ -435,38 +331,12 @@ pub fn lite_parse(tokens: &[Token]) -> (LiteBlock, Option<ParseError>) {
} }
} }
if !curr_command.is_empty() { push_command_to(
match last_connector { &mut curr_pipeline,
TokenContents::OutGreaterThan => { curr_command,
curr_pipeline.push(LiteElement::Redirection( last_connector,
last_connector_span last_connector_span,
.expect("internal error: redirection missing span information"), );
Redirection::Stdout,
curr_command,
));
}
TokenContents::ErrGreaterThan => {
curr_pipeline.push(LiteElement::Redirection(
last_connector_span
.expect("internal error: redirection missing span information"),
Redirection::Stderr,
curr_command,
));
}
TokenContents::OutErrGreaterThan => {
curr_pipeline.push(LiteElement::Redirection(
last_connector_span
.expect("internal error: redirection missing span information"),
Redirection::StdoutAndStderr,
curr_command,
));
}
_ => {
curr_pipeline.push(LiteElement::Command(last_connector_span, curr_command));
}
}
}
if !curr_pipeline.is_empty() { if !curr_pipeline.is_empty() {
block.push(curr_pipeline); block.push(curr_pipeline);
} }
@ -483,3 +353,42 @@ pub fn lite_parse(tokens: &[Token]) -> (LiteBlock, Option<ParseError>) {
(block, error) (block, error)
} }
} }
fn push_command_to(
pipeline: &mut LitePipeline,
command: LiteCommand,
last_connector: TokenContents,
last_connector_span: Option<Span>,
) {
if !command.is_empty() {
match last_connector {
TokenContents::OutGreaterThan => {
pipeline.push(LiteElement::Redirection(
last_connector_span
.expect("internal error: redirection missing span information"),
Redirection::Stdout,
command,
));
}
TokenContents::ErrGreaterThan => {
pipeline.push(LiteElement::Redirection(
last_connector_span
.expect("internal error: redirection missing span information"),
Redirection::Stderr,
command,
));
}
TokenContents::OutErrGreaterThan => {
pipeline.push(LiteElement::Redirection(
last_connector_span
.expect("internal error: redirection missing span information"),
Redirection::StdoutAndStderr,
command,
));
}
_ => {
pipeline.push(LiteElement::Command(last_connector_span, command));
}
}
}
}