Skip to content

Commit

Permalink
more thorough testing around associativity
Browse files Browse the repository at this point in the history
  • Loading branch information
nikomatsakis committed Nov 9, 2023
1 parent 0b1120a commit 13fe33c
Show file tree
Hide file tree
Showing 6 changed files with 479 additions and 63 deletions.
2 changes: 1 addition & 1 deletion crates/formality-core/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ pub type ParseResult<'t, T> = Result<SuccessfulParse<'t, T>, Set<ParseError<'t>>
pub type TokenResult<'t, T> = Result<(T, &'t str), Set<ParseError<'t>>>;

/// Tracks the variables in scope at this point in parsing.
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Default)]
pub struct Scope<L: Language> {
bindings: Vec<(String, CoreParameter<L>)>,
}
Expand Down
159 changes: 159 additions & 0 deletions tests/parser-torture-tests/left_associative.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
use formality_core::{term, test};
use std::sync::Arc;

#[term]
pub enum Expr {
#[cast]
Id(Id),

#[grammar($v0 + $v1)]
#[precedence(1)]
Add(Arc<Expr>, Arc<Expr>),

#[grammar($v0 * $v1)]
#[precedence(2)]
Mul(Arc<Expr>, Arc<Expr>),
}

formality_core::id!(Id);

#[test]
fn add_mul() {
let term: Expr = crate::ptt::term("a + b * c");
expect_test::expect![[r#"
Add(
Id(
a,
),
Mul(
Id(
b,
),
Id(
c,
),
),
)
"#]]
.assert_debug_eq(&term);
}

#[test]
fn mul_add() {
let term: Expr = crate::ptt::term("a * b + c");
expect_test::expect![[r#"
Add(
Mul(
Id(
a,
),
Id(
b,
),
),
Id(
c,
),
)
"#]]
.assert_debug_eq(&term);
}

#[test]
fn add_add() {
let term: Expr = crate::ptt::term("a + b + c");
expect_test::expect![[r#"
Add(
Add(
Id(
a,
),
Id(
b,
),
),
Id(
c,
),
)
"#]]
.assert_debug_eq(&term);
}

#[test]
fn mul_mul() {
let term: Expr = crate::ptt::term("a * b * c");
expect_test::expect![[r#"
Mul(
Mul(
Id(
a,
),
Id(
b,
),
),
Id(
c,
),
)
"#]]
.assert_debug_eq(&term);
}

#[test]
fn mul_mul_mul() {
let term: Expr = crate::ptt::term("a * b * c * d");
expect_test::expect![[r#"
Mul(
Mul(
Mul(
Id(
a,
),
Id(
b,
),
),
Id(
c,
),
),
Id(
d,
),
)
"#]]
.assert_debug_eq(&term);
}

#[test]
fn add_add_mul_add() {
let term: Expr = crate::ptt::term("a + b + c * d + e");
expect_test::expect![[r#"
Add(
Add(
Add(
Id(
a,
),
Id(
b,
),
),
Mul(
Id(
c,
),
Id(
d,
),
),
),
Id(
e,
),
)
"#]]
.assert_debug_eq(&term);
}
24 changes: 22 additions & 2 deletions tests/parser-torture-tests/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
mod ambiguity;
mod grammar;
mod left_associative;
mod none_associative;
mod path;
mod precedence;
mod right_associative;

formality_core::declare_language! {
mod ptt {
Expand All @@ -20,8 +22,26 @@ formality_core::declare_language! {
}
}

/// Used to parse `text` when we expect some remainder
fn expect_remainder<T>(text: &str) -> (T, &str)
where
T: CoreParse<FormalityLang>,
{
match T::parse(&Default::default(), text) {
Ok(parse) => {
let (value, remainder) = parse.finish();
assert!(
!remainder.is_empty(),
"expected to have remainder text, but parsed entire term `{text:?}`"
);
(value, remainder)
}
Err(errs) => panic!("encountered unexpected parse error: {errs:#?}"),
}
}

// Default language for our crate
use formality_core::Fallible;
use formality_core::{parse::CoreParse, Fallible};
use ptt::FormalityLang;

fn main() -> Fallible<()> {
Expand Down
138 changes: 138 additions & 0 deletions tests/parser-torture-tests/none_associative.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
use formality_core::{term, test};
use std::sync::Arc;

use crate::expect_remainder;

#[term]
pub enum Expr {
#[cast]
Id(Id),

#[grammar($v0 + $v1)]
#[precedence(1, none)]
Add(Arc<Expr>, Arc<Expr>),

#[grammar($v0 * $v1)]
#[precedence(2, none)]
Mul(Arc<Expr>, Arc<Expr>),
}

formality_core::id!(Id);

#[test]
fn add_mul() {
let term: Expr = crate::ptt::term("a + b * c");
expect_test::expect![[r#"
Add(
Id(
a,
),
Mul(
Id(
b,
),
Id(
c,
),
),
)
"#]]
.assert_debug_eq(&term);
}

#[test]
fn mul_add() {
let term: Expr = crate::ptt::term("a * b + c");
expect_test::expect![[r#"
Add(
Mul(
Id(
a,
),
Id(
b,
),
),
Id(
c,
),
)
"#]]
.assert_debug_eq(&term);
}

#[test]
fn add_add() {
let term = expect_remainder::<Expr>("a + b + c");
expect_test::expect![[r#"
(
Add(
Id(
a,
),
Id(
b,
),
),
" + c",
)
"#]]
.assert_debug_eq(&term);
}

#[test]
fn mul_mul() {
let term = expect_remainder::<Expr>("a * b * c");
expect_test::expect![[r#"
(
Mul(
Id(
a,
),
Id(
b,
),
),
" * c",
)
"#]]
.assert_debug_eq(&term);
}

#[test]
fn mul_mul_mul() {
let term = expect_remainder::<Expr>("a * b * c * d");
expect_test::expect![[r#"
(
Mul(
Id(
a,
),
Id(
b,
),
),
" * c * d",
)
"#]]
.assert_debug_eq(&term);
}

#[test]
fn add_add_mul_add() {
let term = expect_remainder::<Expr>("a + b + c * d + e");
expect_test::expect![[r#"
(
Add(
Id(
a,
),
Id(
b,
),
),
" + c * d + e",
)
"#]]
.assert_debug_eq(&term);
}
Loading

0 comments on commit 13fe33c

Please sign in to comment.