Write expressions grammar, basic testing.
This commit is contained in:
parent
90a3c40ac3
commit
084ed4a00b
@ -67,11 +67,44 @@ Statement = { VariableDeclaration | CallExpression | AssignmentExpression }
|
||||
VariableDeclaration = { "let" ~ Mutable? ~ Identifier ~ TypeAnnotation? ~ ( "=" ~ Expression )? }
|
||||
|
||||
// Expressions
|
||||
Expression = { CallExpression | AssignmentExpression | Literal | ObjectAccess }
|
||||
ExpressionList = { Expression ~ ( "," ~ Expression )* }
|
||||
Expression = { OrExpression }
|
||||
|
||||
// Calls
|
||||
CallExpression = { ObjectAccess ~ GenericArguments? ~ CallArguments }
|
||||
OrExpression = { AndExpression ~ ( "||" ~ AndExpression )* }
|
||||
AndExpression = { EqualityExpression ~ ( "&&" ~ EqualityExpression )* }
|
||||
|
||||
EqualityExpression = { ComparisonExpression ~ ( ( EqualTo | NotEqualTo ) ~ ComparisonExpression )* }
|
||||
EqualTo = { "==" }
|
||||
NotEqualTo = { "!=" }
|
||||
|
||||
ComparisonExpression = { AdditiveExpression ~ ( ( Greater | Less | GreaterEqual | LessEqual ) ~ AdditiveExpression )* }
|
||||
Greater = { ">" }
|
||||
Less = { "<" }
|
||||
GreaterEqual = { ">=" }
|
||||
LessEqual = { "<=" }
|
||||
|
||||
AdditiveExpression = { MultiplicativeExpression ~ ( ( Add | Subtract ) ~ MultiplicativeExpression )* }
|
||||
Add = { "+" }
|
||||
Subtract = { "-" }
|
||||
|
||||
MultiplicativeExpression = { UnaryExpression ~ ( ( Multiply | Divide | Modulo ) ~ UnaryExpression )* }
|
||||
Multiply = { "*" }
|
||||
Divide = { "/" }
|
||||
Modulo = { "%" }
|
||||
|
||||
UnaryExpression = { ( Not | Negative )* ~ PrimaryExpression ~ ( Call | ( PlusPlus | MinusMinus ) )* }
|
||||
Not = { "!" }
|
||||
Negative = { "-" }
|
||||
PlusPlus = { "++" }
|
||||
MinusMinus = { "--" }
|
||||
|
||||
PrimaryExpression = { Literal | ObjectAccess | ParenthesizedExpression }
|
||||
ParenthesizedExpression = { "(" ~ Expression ~ ")" }
|
||||
|
||||
|
||||
// Call
|
||||
CallExpression = { PrimaryExpression ~ Call+ }
|
||||
Call = { GenericArguments? ~ CallArguments }
|
||||
ExpressionList = { Expression ~ ( "," ~ Expression )* }
|
||||
CallArguments = {
|
||||
( "(" ~ ExpressionList? ~ ")" )
|
||||
| ExpressionList
|
||||
|
@ -10,16 +10,30 @@ mod deimos_parser_tests {
|
||||
use pest::iterators::Pair;
|
||||
use pest::Parser;
|
||||
|
||||
macro_rules! match_inner_rules {
|
||||
($pair:expr; $rule:path; $handle_last:expr) => {{
|
||||
if let $rule = $pair.as_rule() {
|
||||
$handle_last($pair);
|
||||
} else {
|
||||
macro_rules! fail_rule {
|
||||
($pair: expr; $rule:path) => {{
|
||||
panic!(
|
||||
"Expected {} but found {:?}",
|
||||
stringify!($rule),
|
||||
$pair.as_rule()
|
||||
)
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! match_rule {
|
||||
($pair:expr; $rule:path) => {{
|
||||
if $rule != $pair.as_rule() {
|
||||
fail_rule!($pair; $rule);
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! match_inner_rules {
|
||||
($pair:expr; $rule:path; $handle_last:expr) => {{
|
||||
if let $rule = $pair.as_rule() {
|
||||
$handle_last($pair);
|
||||
} else {
|
||||
fail_rule!($pair; $rule);
|
||||
}
|
||||
}};
|
||||
($pair:expr; $head_rule:path $(, $tail_rules:path )* ; $handle_last:expr) => {{
|
||||
@ -31,11 +45,7 @@ mod deimos_parser_tests {
|
||||
$handle_last
|
||||
);
|
||||
} else {
|
||||
panic!(
|
||||
"Expected {} but found {:?}",
|
||||
stringify!($head_rule),
|
||||
$pair.as_rule()
|
||||
)
|
||||
fail_rule!($pair; $head_rule);
|
||||
}
|
||||
}};
|
||||
}
|
||||
@ -61,4 +71,27 @@ mod deimos_parser_tests {
|
||||
assert_eq!(hexadecimal_base.as_str(), "0x123456789abcdef")
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn identifier_call_as_expression() {
|
||||
let pair = parse(Rule::Expression, "foo()");
|
||||
match_inner_rules!(pair; Rule::Expression, Rule::OrExpression, Rule::AndExpression, Rule::EqualityExpression, Rule::ComparisonExpression, Rule::AdditiveExpression, Rule::MultiplicativeExpression, Rule::UnaryExpression; |unary_expression: Pair<Rule>| {
|
||||
let mut unary_pairs = unary_expression.into_inner();
|
||||
let primary_expression = unary_pairs.next().unwrap();
|
||||
match_rule!(primary_expression; Rule::PrimaryExpression);
|
||||
let call = unary_pairs.next().unwrap();
|
||||
match_rule!(call; Rule::Call);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn identifier_call_as_call_expression() {
|
||||
let pair = parse(Rule::CallExpression, "foo()");
|
||||
match_rule!(pair; Rule::CallExpression);
|
||||
let mut call_expression_pairs = pair.into_inner();
|
||||
let primary_expression = call_expression_pairs.next().unwrap();
|
||||
match_rule!(primary_expression; Rule::PrimaryExpression);
|
||||
let call = call_expression_pairs.next().unwrap();
|
||||
match_rule!(call; Rule::Call);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user