diff --git a/crates/oyster_parser/src/parser.rs b/crates/oyster_parser/src/parser.rs index bbf06bc..34756cd 100644 --- a/crates/oyster_parser/src/parser.rs +++ b/crates/oyster_parser/src/parser.rs @@ -144,90 +144,88 @@ impl Iterator for Parser<'_> { }; } - use TokenKind::*; - if let Some(ev) = self.buffer.take() { return Some(ev); } - match self.stack.last() { - None => None, - Some(nt) => match nt { - // XXX: unify Program and CommandSubstitution to avoid duplication - NodeKind::Program => match self.lookahead.kind { - Whitespace => leaf!(Whitespace), - Newlines => leaf!(Newlines), - Semicolon => leaf!(Semicolon), - Comment => leaf!(Comment), - PlainText | DoubleQuote | OpeningParenthesis | EscapedChar => call!(Pipeline), - Pipe => error!(UnexpectedPipe), - ClosingParenthesis => error!(UnexpectedClosingParenthesis), - Eof => chain!(None, ret!()), // return silently - }, - NodeKind::CommandSubstitution => match self.lookahead.kind { - Whitespace => leaf!(Whitespace), - Newlines => leaf!(Newlines), - Semicolon => leaf!(Semicolon), - Comment => leaf!(Comment), - PlainText | DoubleQuote | OpeningParenthesis | EscapedChar => call!(Pipeline), - ClosingParenthesis => match self.stack.get(self.stack.len() - 2) { - Some(&NodeKind::DQuotedString) => { - chain_buf!(leaf!(ClosingParenthesis, String), ret!()) - } - _ => chain_buf!(leaf!(ClosingParenthesis, Command), ret!()), - }, - Pipe => error!(UnexpectedPipe), - Eof => chain_buf!(error!(UnexpectedEof), ret!()), - }, - NodeKind::Pipeline => match self.lookahead.kind { - Whitespace => leaf!(Whitespace), - Comment => leaf!(Comment), - Pipe => chain!(leaf!(Pipe), call!(PipelineCont)), - PlainText | DoubleQuote | OpeningParenthesis | EscapedChar => call!(Command), - Newlines | Semicolon | ClosingParenthesis | Eof => ret!(), - }, - NodeKind::PipelineCont => match self.lookahead.kind { - Whitespace => leaf!(Whitespace), - Newlines => leaf!(Newlines), - Comment => leaf!(Comment), - PlainText | DoubleQuote | OpeningParenthesis | EscapedChar => { - chain!(call!(Command), ret!()) + use TokenKind::*; + + match self.stack.last()? { + // XXX: unify Program and CommandSubstitution to avoid duplication + NodeKind::Program => match self.lookahead.kind { + Whitespace => leaf!(Whitespace), + Newlines => leaf!(Newlines), + Semicolon => leaf!(Semicolon), + Comment => leaf!(Comment), + PlainText | DoubleQuote | OpeningParenthesis | EscapedChar => call!(Pipeline), + Pipe => error!(UnexpectedPipe), + ClosingParenthesis => error!(UnexpectedClosingParenthesis), + Eof => chain!(None, ret!()), // return silently + }, + NodeKind::CommandSubstitution => match self.lookahead.kind { + Whitespace => leaf!(Whitespace), + Newlines => leaf!(Newlines), + Semicolon => leaf!(Semicolon), + Comment => leaf!(Comment), + PlainText | DoubleQuote | OpeningParenthesis | EscapedChar => call!(Pipeline), + ClosingParenthesis => match self.stack.get(self.stack.len() - 2) { + Some(&NodeKind::DQuotedString) => { + chain_buf!(leaf!(ClosingParenthesis, String), ret!()) } - Semicolon => chain_buf!(chain!(error!(UnexpectedSemicolon), ret!()), ret!()), - Pipe => chain!(error!(UnexpectedPipe), ret!()), - ClosingParenthesis => chain!(error!(UnexpectedClosingParenthesis), ret!()), - Eof => chain!(error!(UnexpectedEof), ret!()), - }, - NodeKind::Command => match self.lookahead.kind { - Whitespace => leaf!(Whitespace), - Comment => leaf!(Comment), - PlainText | DoubleQuote | OpeningParenthesis | EscapedChar => call!(Word), - Newlines | Semicolon | Pipe | ClosingParenthesis | Eof => ret!(), - }, - NodeKind::Word => match self.lookahead.kind { - PlainText => leaf!(PlainText), - EscapedChar => leaf!(EscapedChar), - DoubleQuote => chain_buf!(call!(DQuotedString), leaf!(DoubleQuote, String)), - OpeningParenthesis => { - chain_buf!(call!(CommandSubstitution), leaf!(OpeningParenthesis)) - } - Comment | Whitespace | Newlines | Semicolon | Pipe | ClosingParenthesis - | Eof => ret!(), - }, - NodeKind::DQuotedString => match self.lookahead.kind { - PlainText => leaf!(PlainText, String), - EscapedChar => leaf!(EscapedChar, String), - DoubleQuote => chain_buf!(leaf!(DoubleQuote, Command), ret!()), - OpeningParenthesis => chain_buf!( - call!(CommandSubstitution), - leaf!(OpeningParenthesis, Command) - ), - ClosingParenthesis => error!(UnexpectedClosingParenthesis, String), - Eof => chain_buf!(error!(UnexpectedEof, Command), ret!()), - _ => unreachable!(), + _ => chain_buf!(leaf!(ClosingParenthesis, Command), ret!()), }, + Pipe => error!(UnexpectedPipe), + Eof => chain_buf!(error!(UnexpectedEof), ret!()), + }, + NodeKind::Pipeline => match self.lookahead.kind { + Whitespace => leaf!(Whitespace), + Comment => leaf!(Comment), + Pipe => chain!(leaf!(Pipe), call!(PipelineCont)), + PlainText | DoubleQuote | OpeningParenthesis | EscapedChar => call!(Command), + Newlines | Semicolon | ClosingParenthesis | Eof => ret!(), + }, + NodeKind::PipelineCont => match self.lookahead.kind { + Whitespace => leaf!(Whitespace), + Newlines => leaf!(Newlines), + Comment => leaf!(Comment), + PlainText | DoubleQuote | OpeningParenthesis | EscapedChar => { + chain!(call!(Command), ret!()) + } + Semicolon => chain_buf!(chain!(error!(UnexpectedSemicolon), ret!()), ret!()), + Pipe => chain!(error!(UnexpectedPipe), ret!()), + ClosingParenthesis => chain!(error!(UnexpectedClosingParenthesis), ret!()), + Eof => chain!(error!(UnexpectedEof), ret!()), + }, + NodeKind::Command => match self.lookahead.kind { + Whitespace => leaf!(Whitespace), + Comment => leaf!(Comment), + PlainText | DoubleQuote | OpeningParenthesis | EscapedChar => call!(Word), + Newlines | Semicolon | Pipe | ClosingParenthesis | Eof => ret!(), + }, + NodeKind::Word => match self.lookahead.kind { + PlainText => leaf!(PlainText), + EscapedChar => leaf!(EscapedChar), + DoubleQuote => chain_buf!(call!(DQuotedString), leaf!(DoubleQuote, String)), + OpeningParenthesis => { + chain_buf!(call!(CommandSubstitution), leaf!(OpeningParenthesis)) + } + Comment | Whitespace | Newlines | Semicolon | Pipe | ClosingParenthesis | Eof => { + ret!() + } + }, + NodeKind::DQuotedString => match self.lookahead.kind { + PlainText => leaf!(PlainText, String), + EscapedChar => leaf!(EscapedChar, String), + DoubleQuote => chain_buf!(leaf!(DoubleQuote, Command), ret!()), + OpeningParenthesis => chain_buf!( + call!(CommandSubstitution), + leaf!(OpeningParenthesis, Command) + ), + ClosingParenthesis => error!(UnexpectedClosingParenthesis, String), + Eof => chain_buf!(error!(UnexpectedEof, Command), ret!()), _ => unreachable!(), }, + _ => unreachable!(), } } }