Work on object access and number literal grammar; basic parser testing.
This commit is contained in:
parent
815168603c
commit
90a3c40ac3
@ -67,25 +67,38 @@ Statement = { VariableDeclaration | CallExpression | AssignmentExpression }
|
||||
VariableDeclaration = { "let" ~ Mutable? ~ Identifier ~ TypeAnnotation? ~ ( "=" ~ Expression )? }
|
||||
|
||||
// Expressions
|
||||
Expression = { CallExpression | AssignmentExpression | Literal | FullyQualifiedName }
|
||||
Expression = { CallExpression | AssignmentExpression | Literal | ObjectAccess }
|
||||
ExpressionList = { Expression ~ ( "," ~ Expression )* }
|
||||
|
||||
// Calls
|
||||
CallExpression = { FullyQualifiedName ~ GenericArguments ~ CallArguments }
|
||||
CallExpression = { ObjectAccess ~ GenericArguments? ~ CallArguments }
|
||||
CallArguments = {
|
||||
( "(" ~ ExpressionList? ~")")
|
||||
| ExpressionList
|
||||
}
|
||||
|
||||
// Assignment
|
||||
AssignmentExpression = { FullyQualifiedName ~ "=" ~ Expression }
|
||||
AssignmentExpression = { ObjectAccess ~ "=" ~ Expression }
|
||||
|
||||
// Object
|
||||
ObjectAccess = { FullyQualifiedName ~ ( "." ~ Identifier )* }
|
||||
|
||||
// Literals
|
||||
Literal = { NumberLiteral | StringLiteral | BooleanLiteral | NullLiteral }
|
||||
|
||||
NumberLiteral = { IntLiteral }
|
||||
IntLiteral = { '0'..'9'+ }
|
||||
LongLiteral = { '0'..'9'+ ~ "L" }
|
||||
NumberLiteral = { LongLiteral | IntLiteral }
|
||||
|
||||
IntLiteral = { NumberBase }
|
||||
LongLiteral = ${ NumberBase ~ "L" }
|
||||
|
||||
NumberBase = { DecimalBase | BinaryBase | HexadecimalBase }
|
||||
|
||||
DecimalBase = @{ DecimalStartDigit ~ Digit* }
|
||||
BinaryBase = @{ "0b" ~ Digit* }
|
||||
DecimalStartDigit = { '1'..'9' }
|
||||
Digit = { '0'..'9'+ }
|
||||
HexadecimalBase = @{ "0x" ~ HexadecimalDigit+ }
|
||||
HexadecimalDigit = { '0'..'9' | 'a'..'f' }
|
||||
|
||||
StringLiteral = ${ "\"" ~ StringInner ~ "\"" }
|
||||
StringInner = @{ StringChar* }
|
||||
|
@ -3,3 +3,62 @@ use pest_derive::Parser;
|
||||
#[derive(Parser)]
|
||||
#[grammar = "parser/deimos.pest"]
|
||||
pub struct DeimosParser;
|
||||
|
||||
#[cfg(test)]
|
||||
mod deimos_parser_tests {
|
||||
use crate::parser::{DeimosParser, Rule};
|
||||
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 {
|
||||
panic!(
|
||||
"Expected {} but found {:?}",
|
||||
stringify!($rule),
|
||||
$pair.as_rule()
|
||||
)
|
||||
}
|
||||
}};
|
||||
($pair:expr; $head_rule:path $(, $tail_rules:path )* ; $handle_last:expr) => {{
|
||||
if let $head_rule = $pair.as_rule() {
|
||||
let inner = $pair.into_inner().next().unwrap();
|
||||
match_inner_rules!(
|
||||
inner;
|
||||
$( $tail_rules ),*;
|
||||
$handle_last
|
||||
);
|
||||
} else {
|
||||
panic!(
|
||||
"Expected {} but found {:?}",
|
||||
stringify!($head_rule),
|
||||
$pair.as_rule()
|
||||
)
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
fn parse(rule: Rule, input: &str) -> Pair<Rule> {
|
||||
let pair = DeimosParser::parse(rule, input).unwrap().next().unwrap();
|
||||
dbg!(&pair);
|
||||
pair
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hex_int() {
|
||||
let pair = parse(Rule::IntLiteral, "0x1234abcd");
|
||||
match_inner_rules!(pair; Rule::IntLiteral, Rule::NumberBase, Rule::HexadecimalBase; |hexadecimal_base: Pair<Rule>| {
|
||||
assert_eq!(hexadecimal_base.as_str(), "0x1234abcd")
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hex_long() {
|
||||
let pair = parse(Rule::LongLiteral, "0x123456789abcdefL");
|
||||
match_inner_rules!(pair; Rule::LongLiteral, Rule::NumberBase, Rule::HexadecimalBase; |hexadecimal_base: Pair<Rule>| {
|
||||
assert_eq!(hexadecimal_base.as_str(), "0x123456789abcdef")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user