Merge pull request #596 from Porges/improve-pipeline-parsing

Improve parsing of pipelines, require pipes between segments
This commit is contained in:
Yehuda Katz 2019-09-04 09:41:49 -07:00 committed by GitHub
commit fd715e1775
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 29 additions and 21 deletions

View file

@ -552,11 +552,11 @@ pub fn node(input: NomSpan) -> IResult<NomSpan, TokenNode> {
pub fn pipeline(input: NomSpan) -> IResult<NomSpan, TokenNode> { pub fn pipeline(input: NomSpan) -> IResult<NomSpan, TokenNode> {
trace_step(input, "pipeline", |input| { trace_step(input, "pipeline", |input| {
let start = input.offset; let start = input.offset;
let (input, head) = opt(tuple((raw_call, opt(space1), opt(tag("|")))))(input)?; let (input, head) = opt(tuple((opt(space1), raw_call, opt(space1))))(input)?;
let (input, items) = trace_step( let (input, items) = trace_step(
input, input,
"many0", "many0",
many0(tuple((opt(space1), raw_call, opt(space1), opt(tag("|"))))), many0(tuple((tag("|"), opt(space1), raw_call, opt(space1)))),
)?; )?;
let (input, tail) = opt(space1)(input)?; let (input, tail) = opt(space1)(input)?;
@ -582,28 +582,37 @@ pub fn pipeline(input: NomSpan) -> IResult<NomSpan, TokenNode> {
} }
fn make_call_list( fn make_call_list(
head: Option<(Tagged<CallNode>, Option<NomSpan>, Option<NomSpan>)>, head: Option<(
items: Vec<(
Option<NomSpan>, Option<NomSpan>,
Tagged<CallNode>, Tagged<CallNode>,
Option<NomSpan>
)>,
items: Vec<(
NomSpan,
Option<NomSpan>, Option<NomSpan>,
Tagged<CallNode>,
Option<NomSpan>, Option<NomSpan>,
)>, )>,
) -> Vec<PipelineElement> { ) -> Vec<PipelineElement> {
let mut out = vec![]; let mut out = vec![];
if let Some(head) = head { if let Some(head) = head {
let el = PipelineElement::new(None, head.0, head.1.map(Span::from), head.2.map(Span::from)); let el = PipelineElement::new(
None,
head.0.map(Span::from),
head.1,
head.2.map(Span::from));
out.push(el); out.push(el);
} }
for (ws1, call, ws2, pipe) in items { for (pipe, ws1, call, ws2) in items {
let el = PipelineElement::new( let el = PipelineElement::new(
Some(pipe).map(Span::from),
ws1.map(Span::from), ws1.map(Span::from),
call, call,
ws2.map(Span::from), ws2.map(Span::from));
pipe.map(Span::from),
);
out.push(el); out.push(el);
} }

View file

@ -11,9 +11,9 @@ pub struct Pipeline {
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Getters, new)] #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Getters, new)]
pub struct PipelineElement { pub struct PipelineElement {
pub pipe: Option<Span>,
pub pre_ws: Option<Span>, pub pre_ws: Option<Span>,
#[get = "pub(crate)"] #[get = "pub(crate)"]
call: Tagged<CallNode>, call: Tagged<CallNode>,
pub post_ws: Option<Span>, pub post_ws: Option<Span>,
pub post_pipe: Option<Span>,
} }

View file

@ -47,32 +47,31 @@ impl TokenTreeBuilder {
.next() .next()
.expect("A pipeline must contain at least one element"); .expect("A pipeline must contain at least one element");
let pipe = None;
let pre_span = pre.map(|pre| b.consume(&pre)); let pre_span = pre.map(|pre| b.consume(&pre));
let call = call(b); let call = call(b);
let post_span = post.map(|post| b.consume(&post)); let post_span = post.map(|post| b.consume(&post));
let pipe = input.peek().map(|_| Span::from(b.consume("|")));
out.push(PipelineElement::new( out.push(PipelineElement::new(
pipe,
pre_span.map(Span::from), pre_span.map(Span::from),
call, call,
post_span.map(Span::from), post_span.map(Span::from)));
pipe,
));
loop { loop {
match input.next() { match input.next() {
None => break, None => break,
Some((pre, call, post)) => { Some((pre, call, post)) => {
let pipe = Some(Span::from(b.consume("|")));
let pre_span = pre.map(|pre| b.consume(&pre)); let pre_span = pre.map(|pre| b.consume(&pre));
let call = call(b); let call = call(b);
let post_span = post.map(|post| b.consume(&post)); let post_span = post.map(|post| b.consume(&post));
let pipe = input.peek().map(|_| Span::from(b.consume("|")));
out.push(PipelineElement::new( out.push(PipelineElement::new(
pipe,
pre_span.map(Span::from), pre_span.map(Span::from),
call, call,
post_span.map(Span::from), post_span.map(Span::from),
pipe,
)); ));
} }
} }

View file

@ -147,6 +147,10 @@ fn paint_token_node(token_node: &TokenNode, line: &str) -> String {
fn paint_pipeline_element(pipeline_element: &PipelineElement, line: &str) -> String { fn paint_pipeline_element(pipeline_element: &PipelineElement, line: &str) -> String {
let mut styled = String::new(); let mut styled = String::new();
if let Some(_) = pipeline_element.pipe {
styled.push_str(&Color::Purple.paint("|"));
}
if let Some(ws) = pipeline_element.pre_ws { if let Some(ws) = pipeline_element.pre_ws {
styled.push_str(&Color::White.normal().paint(ws.slice(line))); styled.push_str(&Color::White.normal().paint(ws.slice(line)));
} }
@ -168,10 +172,6 @@ fn paint_pipeline_element(pipeline_element: &PipelineElement, line: &str) -> Str
styled.push_str(&Color::White.normal().paint(ws.slice(line))); styled.push_str(&Color::White.normal().paint(ws.slice(line)));
} }
if let Some(_) = pipeline_element.post_pipe {
styled.push_str(&Color::Purple.paint("|"));
}
styled.to_string() styled.to_string()
} }