Write expressions grammar, basic testing.
This commit is contained in:
parent
90a3c40ac3
commit
084ed4a00b
@ -67,13 +67,46 @@ Statement = { VariableDeclaration | CallExpression | AssignmentExpression }
|
|||||||
VariableDeclaration = { "let" ~ Mutable? ~ Identifier ~ TypeAnnotation? ~ ( "=" ~ Expression )? }
|
VariableDeclaration = { "let" ~ Mutable? ~ Identifier ~ TypeAnnotation? ~ ( "=" ~ Expression )? }
|
||||||
|
|
||||||
// Expressions
|
// Expressions
|
||||||
Expression = { CallExpression | AssignmentExpression | Literal | ObjectAccess }
|
Expression = { OrExpression }
|
||||||
ExpressionList = { Expression ~ ( "," ~ Expression )* }
|
|
||||||
|
|
||||||
// Calls
|
OrExpression = { AndExpression ~ ( "||" ~ AndExpression )* }
|
||||||
CallExpression = { ObjectAccess ~ GenericArguments? ~ CallArguments }
|
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 = {
|
CallArguments = {
|
||||||
( "(" ~ ExpressionList? ~")")
|
( "(" ~ ExpressionList? ~ ")" )
|
||||||
| ExpressionList
|
| ExpressionList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,16 +10,30 @@ mod deimos_parser_tests {
|
|||||||
use pest::iterators::Pair;
|
use pest::iterators::Pair;
|
||||||
use pest::Parser;
|
use pest::Parser;
|
||||||
|
|
||||||
macro_rules! match_inner_rules {
|
macro_rules! fail_rule {
|
||||||
($pair:expr; $rule:path; $handle_last:expr) => {{
|
($pair: expr; $rule:path) => {{
|
||||||
if let $rule = $pair.as_rule() {
|
|
||||||
$handle_last($pair);
|
|
||||||
} else {
|
|
||||||
panic!(
|
panic!(
|
||||||
"Expected {} but found {:?}",
|
"Expected {} but found {:?}",
|
||||||
stringify!($rule),
|
stringify!($rule),
|
||||||
$pair.as_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) => {{
|
($pair:expr; $head_rule:path $(, $tail_rules:path )* ; $handle_last:expr) => {{
|
||||||
@ -31,11 +45,7 @@ mod deimos_parser_tests {
|
|||||||
$handle_last
|
$handle_last
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
panic!(
|
fail_rule!($pair; $head_rule);
|
||||||
"Expected {} but found {:?}",
|
|
||||||
stringify!($head_rule),
|
|
||||||
$pair.as_rule()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
@ -61,4 +71,27 @@ mod deimos_parser_tests {
|
|||||||
assert_eq!(hexadecimal_base.as_str(), "0x123456789abcdef")
|
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