Add indoc and indexing to grammar.
This commit is contained in:
parent
f5a82c414c
commit
15abcc92d3
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -148,6 +148,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"codespan-reporting",
|
"codespan-reporting",
|
||||||
|
"indoc",
|
||||||
"log",
|
"log",
|
||||||
"pest",
|
"pest",
|
||||||
"pest_derive",
|
"pest_derive",
|
||||||
@ -179,6 +180,12 @@ version = "0.5.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indoc"
|
||||||
|
version = "2.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "is_terminal_polyfill"
|
name = "is_terminal_polyfill"
|
||||||
version = "1.70.1"
|
version = "1.70.1"
|
||||||
|
@ -17,3 +17,4 @@ clap = { version = "4.5.23", features = ["derive"] }
|
|||||||
pest_derive = "2.7.14"
|
pest_derive = "2.7.14"
|
||||||
codespan-reporting = "0.12.0"
|
codespan-reporting = "0.12.0"
|
||||||
log = "0.4.27"
|
log = "0.4.27"
|
||||||
|
indoc = "2.0.6"
|
||||||
|
@ -95,6 +95,7 @@ Borrow = { "&" }
|
|||||||
Star = { "*" }
|
Star = { "*" }
|
||||||
LeftShift = { "<<" }
|
LeftShift = { "<<" }
|
||||||
RightShift = { ">>" }
|
RightShift = { ">>" }
|
||||||
|
Index = { "[]" }
|
||||||
|
|
||||||
Operator = {
|
Operator = {
|
||||||
Or
|
Or
|
||||||
@ -118,6 +119,9 @@ Operator = {
|
|||||||
| Spread
|
| Spread
|
||||||
| Borrow
|
| Borrow
|
||||||
| Star
|
| Star
|
||||||
|
| LeftShift
|
||||||
|
| RightShift
|
||||||
|
| Index
|
||||||
}
|
}
|
||||||
|
|
||||||
// Names
|
// Names
|
||||||
@ -429,9 +433,9 @@ FunctionModifier = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FunctionBody = {
|
FunctionBody = {
|
||||||
FunctionEqualsBody
|
FunctionAliasBody
|
||||||
|
| FunctionEqualsBody
|
||||||
| BlockStatement
|
| BlockStatement
|
||||||
| FunctionAliasBody
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionEqualsBody = {
|
FunctionEqualsBody = {
|
||||||
@ -652,9 +656,18 @@ ParenthesizedExpression = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ObjectAccess = {
|
ObjectAccess = {
|
||||||
|
( ObjectProperty | ObjectIndex )+
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectProperty = {
|
||||||
"."
|
"."
|
||||||
~ Identifier
|
~ Identifier
|
||||||
~ ( "." ~ Identifier )*
|
}
|
||||||
|
|
||||||
|
ObjectIndex = {
|
||||||
|
"["
|
||||||
|
~ Expression
|
||||||
|
~ "]"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calls
|
// Calls
|
||||||
|
@ -7,8 +7,8 @@ pub struct DeimosParser;
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod deimos_parser_tests {
|
mod deimos_parser_tests {
|
||||||
use crate::parser::{DeimosParser, Rule};
|
use crate::parser::{DeimosParser, Rule};
|
||||||
use pest::iterators::Pair;
|
use indoc::indoc;
|
||||||
use pest::{Parser};
|
use pest::Parser;
|
||||||
|
|
||||||
macro_rules! fail_rule {
|
macro_rules! fail_rule {
|
||||||
($pair: expr; $rule:path) => {{
|
($pair: expr; $rule:path) => {{
|
||||||
@ -28,70 +28,40 @@ mod deimos_parser_tests {
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! match_inner_rules {
|
fn parses_to(rule: Rule, input: &str) {
|
||||||
($pair:expr; $rule:path; $handle_last:expr) => {{
|
let parse_result = DeimosParser::parse(rule, input);
|
||||||
if let $rule = $pair.as_rule() {
|
if let Err(e) = parse_result {
|
||||||
$handle_last($pair);
|
panic!("Parsing failed.\n{}", e);
|
||||||
} else {
|
} else {
|
||||||
fail_rule!($pair; $rule);
|
let mut pairs = parse_result.unwrap();
|
||||||
|
let first = pairs.next().unwrap();
|
||||||
|
match_rule!(first; 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 {
|
|
||||||
fail_rule!($pair; $head_rule);
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse(rule: Rule, input: &str) -> Pair<Rule> {
|
|
||||||
let pair = DeimosParser::parse(rule, input)
|
|
||||||
.expect("Parsing failed.")
|
|
||||||
.next()
|
|
||||||
.unwrap();
|
|
||||||
dbg!(&pair);
|
|
||||||
pair
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn hex_int() {
|
fn hex_int() {
|
||||||
let pair = parse(Rule::IntLiteral, "0x1234abcd");
|
parses_to(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]
|
#[test]
|
||||||
fn hex_long() {
|
fn hex_long() {
|
||||||
let pair = parse(Rule::LongLiteral, "0x123456789abcdefL");
|
parses_to(Rule::LongLiteral, "0x123456789abcdefL");
|
||||||
match_inner_rules!(pair; Rule::LongLiteral, Rule::NumberBase, Rule::HexadecimalBase; |hexadecimal_base: Pair<Rule>| {
|
|
||||||
assert_eq!(hexadecimal_base.as_str(), "0x123456789abcdef")
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn identifier_call_as_expression() {
|
fn suffix_expression_call_single_identifier() {
|
||||||
parse(Rule::Expression, "foo()");
|
parses_to(Rule::SuffixExpression, "foo()");
|
||||||
}
|
}
|
||||||
|
|
||||||
mod smoke_screen_tests {
|
|
||||||
use crate::parser::deimos_parser_tests::parse;
|
|
||||||
use crate::parser::Rule;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn simple_interface() {
|
fn simple_interface() {
|
||||||
parse(Rule::CompilationUnit, "pub int Simple { fn foo() -> Void }");
|
parses_to(Rule::CompilationUnit, "pub int Simple { fn foo() -> Void }");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn interface_with_op() {
|
fn interface_with_op() {
|
||||||
parse(
|
parses_to(
|
||||||
Rule::CompilationUnit,
|
Rule::CompilationUnit,
|
||||||
"pub int Callable { op () () -> Void }",
|
"pub int Callable { op () () -> Void }",
|
||||||
);
|
);
|
||||||
@ -99,10 +69,24 @@ mod deimos_parser_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn interface_with_alias() {
|
fn interface_with_alias() {
|
||||||
parse(
|
parses_to(
|
||||||
Rule::CompilationUnit,
|
Rule::CompilationUnit,
|
||||||
"pub int Callable {\n fn call() -> Void\n op () () -> Void alias call\n}",
|
indoc! {"
|
||||||
|
pub int Callable {
|
||||||
|
fn call() -> Void
|
||||||
|
def op () () -> Void alias call
|
||||||
|
}
|
||||||
|
"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn index_identifier() {
|
||||||
|
parses_to(Rule::SuffixExpression, "foo[0]");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn chained_index_call_on_identifier() {
|
||||||
|
parses_to(Rule::SuffixExpression, "foo[0]()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user