nushell/src/parser/parser.lalrpop
2019-06-01 05:21:03 +12:00

136 lines
4.2 KiB
Plaintext

#![allow(unused)]
use std::str::FromStr;
use crate::parser::ast::*;
use crate::prelude::*;
use crate::parser::lexer::{SpannedToken, Token};
use byte_unit::Byte;
grammar<'input>;
pub Pipeline: Pipeline = {
<first:Command> => Pipeline::new(vec![first]),
<first:Command> <rest: ( "|" <Command> )+> => Pipeline::from_parts(first, rest),
}
Command: ParsedCommand = {
<command:BarePath> => ParsedCommand::new(command.to_string(), vec![]),
<command:BarePath> <expr:Expr+> => ParsedCommand::new(command.to_string(), expr),
<command:BarePath> <expr:BinaryExpression> => ParsedCommand::new(command.to_string(), vec![expr]),
}
Leaf: Expression = {
<String> => Expression::Leaf(Leaf::String(<>)),
<Int> => Expression::Leaf(Leaf::Int(<>)),
<UnitsNum> => Expression::Leaf(Leaf::Int(<>)),
<Variable> => Expression::VariableReference(<>),
}
BinaryExpression: Expression = {
<left:Expr> <op:Operator> <right:Expr> => Expression::Binary(Box::new(Binary::new(left, op, right))),
}
Parenthesized: Expression = {
"(" <Leaf> ")" => Expression::Parenthesized(Box::new(Parenthesized::new(<>))),
"(" <BinaryExpression> ")" => Expression::Parenthesized(Box::new(Parenthesized::new(<>))),
}
AtomicExpression: Expression = {
<Parenthesized>,
<Leaf>,
}
Block: Expression = {
"{" <AtomicExpression> "}" => Expression::Block(Box::new(Block::new(<>))),
"{" <BinaryExpression> "}" => Expression::Block(Box::new(Block::new(<>))),
}
WholeExpression: Expression = {
<AtomicExpression>,
<Block>,
}
PathHead: Expression = {
<WholeExpression>,
<BarePath> => Expression::Leaf(Leaf::Bare(<>)),
<Flag> => Expression::Flag(<>),
}
PathExpression: Expression = {
<head:WholeExpression> <tail: ( "???." <Member> )+> => Expression::Path(Box::new(Path::new(head, tail)))
}
Expr: Expression = {
<PathExpression>,
<PathHead>
}
Variable: Variable = {
"$" <"variable"> => Variable::from_str(<>.as_slice()).unwrap(),
}
Member: String = {
<"member"> => <>.to_string(),
<String>
}
Operator: Operator = {
"==" => Operator::Equal,
"!=" => Operator::NotEqual,
"<" => Operator::LessThan,
">" => Operator::GreaterThan,
"<=" => Operator::LessThanOrEqual,
">=" => Operator::GreaterThanOrEqual
}
Flag: Flag = {
"-" <BarePath> => Flag::Shorthand(<>.to_string()),
"--" <BarePath> => Flag::Longhand(<>.to_string()),
}
String: String = {
<"sqstring"> => <>.as_slice()[1..(<>.as_slice().len() - 1)].to_string(),
<"dqstring"> => <>.as_slice()[1..(<>.as_slice().len() - 1)].to_string()
}
BarePath: BarePath = {
<head: "bare"> <tail: ( "???." <"member"> )*> => BarePath::from_tokens(head, tail)
}
Int: i64 = {
<"num"> => i64::from_str(<>.as_slice()).unwrap()
}
UnitsNum: i64 = {
<"unitsnum"> => Byte::from_string(<>.as_slice()).unwrap().get_bytes() as i64
}
extern {
type Location = usize;
type Error = ShellError;
enum SpannedToken<'input> {
"|" => SpannedToken { token: Token::Pipe, .. },
"(" => SpannedToken { token: Token::OpenParen, .. },
")" => SpannedToken { token: Token::CloseParen, .. },
"{" => SpannedToken { token: Token::OpenBrace, .. },
"}" => SpannedToken { token: Token::CloseBrace, .. },
"==" => SpannedToken { token: Token::OpEq, .. },
"!=" => SpannedToken { token: Token::OpNeq, .. },
"<" => SpannedToken { token: Token::OpLt, .. },
"<=" => SpannedToken { token: Token::OpLte, .. },
">" => SpannedToken { token: Token::OpGt, .. },
">=" => SpannedToken { token: Token::OpGte, .. },
"-" => SpannedToken { token: Token::Dash, .. },
"--" => SpannedToken { token: Token::DashDash, .. },
"$" => SpannedToken { token: Token::Dollar, .. },
"???." => SpannedToken { token: Token::PathDot, .. },
"num" => SpannedToken { token: Token::Num, .. },
"member" => SpannedToken { token: Token::Member, .. },
"variable" => SpannedToken { token: Token::Variable, .. },
"bare" => SpannedToken { token: Token::Bare, .. },
"dqstring" => SpannedToken { token: Token::DQString, .. },
"sqstring" => SpannedToken { token: Token::SQString, .. },
"unitsnum" => SpannedToken { token: Token::UnitsNum, .. },
}
}