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 )? }
|
VariableDeclaration = { "let" ~ Mutable? ~ Identifier ~ TypeAnnotation? ~ ( "=" ~ Expression )? }
|
||||||
|
|
||||||
// Expressions
|
// Expressions
|
||||||
Expression = { CallExpression | AssignmentExpression | Literal | FullyQualifiedName }
|
Expression = { CallExpression | AssignmentExpression | Literal | ObjectAccess }
|
||||||
ExpressionList = { Expression ~ ( "," ~ Expression )* }
|
ExpressionList = { Expression ~ ( "," ~ Expression )* }
|
||||||
|
|
||||||
// Calls
|
// Calls
|
||||||
CallExpression = { FullyQualifiedName ~ GenericArguments ~ CallArguments }
|
CallExpression = { ObjectAccess ~ GenericArguments? ~ CallArguments }
|
||||||
CallArguments = {
|
CallArguments = {
|
||||||
( "(" ~ ExpressionList? ~")")
|
( "(" ~ ExpressionList? ~")")
|
||||||
| ExpressionList
|
| ExpressionList
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assignment
|
// Assignment
|
||||||
AssignmentExpression = { FullyQualifiedName ~ "=" ~ Expression }
|
AssignmentExpression = { ObjectAccess ~ "=" ~ Expression }
|
||||||
|
|
||||||
|
// Object
|
||||||
|
ObjectAccess = { FullyQualifiedName ~ ( "." ~ Identifier )* }
|
||||||
|
|
||||||
// Literals
|
// Literals
|
||||||
Literal = { NumberLiteral | StringLiteral | BooleanLiteral | NullLiteral }
|
Literal = { NumberLiteral | StringLiteral | BooleanLiteral | NullLiteral }
|
||||||
|
|
||||||
NumberLiteral = { IntLiteral }
|
NumberLiteral = { LongLiteral | IntLiteral }
|
||||||
IntLiteral = { '0'..'9'+ }
|
|
||||||
LongLiteral = { '0'..'9'+ ~ "L" }
|
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 ~ "\"" }
|
StringLiteral = ${ "\"" ~ StringInner ~ "\"" }
|
||||||
StringInner = @{ StringChar* }
|
StringInner = @{ StringChar* }
|
||||||
|
@ -3,3 +3,62 @@ use pest_derive::Parser;
|
|||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[grammar = "parser/deimos.pest"]
|
#[grammar = "parser/deimos.pest"]
|
||||||
pub struct DeimosParser;
|
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