nushell/src/parser/parser.lalrpop
2019-05-28 19:19:16 +12:00

92 lines
2.5 KiB
Text

use std::str::FromStr;
use byte_unit::Byte;
use crate::parser::ast::*;
grammar;
pub Pipeline: Pipeline = {
<first:Command> => Pipeline::new(vec![first]),
<first:Command> <rest: ( "|" <Command> )+> => Pipeline::from_parts(first, rest),
}
Command: ParsedCommand = {
<command:RawBareWord> <expr:Expr*> => ParsedCommand::new(command, expr),
<command:RawBareWord> <expr:BinaryExpression> => ParsedCommand::new(command, vec![expr]),
}
Leaf: Expression = {
<String> => Expression::Leaf(Leaf::String(<>)),
<Num> => Expression::Leaf(Leaf::Int(<>)),
<Size> => Expression::Leaf(Leaf::Int(<>)),
<Variable> => Expression::VariableReference(<>),
}
BinaryExpression: Expression = {
<left:Expr> <op:Operator> <right:Leaf> => 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>,
}
PathExpression: Expression = {
<head:WholeExpression> <tail: ( "." <Member> )*> => Expression::Path(Box::new(Path::new(head, tail)))
}
Expr: Expression = {
<RawBareWord> => Expression::Leaf(Leaf::Bare(<>)),
<PathExpression>
}
Variable: Variable = {
"$true" => Variable::True,
"$false" => Variable::False,
"$it" => Variable::It,
"$" <RawBareWord> => Variable::Other(<>.to_string()),
}
Member: String = {
<RawBareWord>,
<String>
}
Operator: Operator = {
"==" => Operator::Equal,
"!=" => Operator::NotEqual,
"<" => Operator::LessThan,
">" => Operator::GreaterThan,
"<=" => Operator::LessThanOrEqual,
">=" => Operator::GreaterThanOrEqual
}
Flag: Flag = {
"-" <RawBareWord> => Flag::Shorthand(<>.to_string()),
"--" <RawBareWord> => Flag::Longhand(<>.to_string()),
}
String: String = {
SQString,
DQString,
}
RawBareWord: String = <s:r#"[^0-9"'\-][^\s"']*"#> => <>.to_string();
DQString: String = <s:r#""([^"]|\\")*""#> => s[1..s.len() - 1].to_string();
SQString: String = <s:r#"'([^']|\\')*'"#> => s[1..s.len() - 1].to_string();
Num: i64 = <s:r"-?[0-9]+"> => i64::from_str(s).unwrap();
Size: i64 = <s:r"-?[0-9]+[A-Za-z]+"> => Byte::from_string(s).unwrap().get_bytes() as i64;