diff --git a/pestfoamtest/src/foam.pest b/pestfoamtest/src/foam.pest index 2ecdbd1..fbeb306 100644 --- a/pestfoamtest/src/foam.pest +++ b/pestfoamtest/src/foam.pest @@ -1,4 +1,15 @@ +whitespace = _{ " " | "\t" | "\r" | "\n" } multi_comment = { "/*" ~ (!"*/" ~ ANY)* ~ "*/" } single_comment = { "//" ~ (!NEWLINE ~ ANY)* } +identifier = { ASCII_ALPHA+ ~ (ASCII_ALPHA | ASCII_DIGIT | "_")* } +rvalue = { (!";" ~ ANY)+ } +attribution = { identifier ~ whitespace+ ~ rvalue ~ ";" } +dictionary = { identifier ~ whitespace+ ~ "{" ~ (dictionary | attribution | whitespace)+ ~ "}" } -field = { (ASCII_DIGIT | "." | "-")+ } +file = { SOI ~ ( + whitespace + | multi_comment + | single_comment + | dictionary + | attribution)* + ~ EOI } diff --git a/pestfoamtest/src/lib.rs b/pestfoamtest/src/lib.rs new file mode 100644 index 0000000..a88819e --- /dev/null +++ b/pestfoamtest/src/lib.rs @@ -0,0 +1,90 @@ +//! Parse a Foam file into a major structure. + +use pest_derive::Parser; + +#[derive(Parser)] +#[grammar = "foam.pest"] +pub struct Foam; + +#[cfg(test)] +mod test { + use super::*; + use pest::Parser; + + #[test] + fn multi_comment() { + let parse = Foam::parse(Rule::multi_comment, "/* this is comment */"); + assert!(parse.is_ok()); + } + + #[test] + fn broken_multi() { + let parse = Foam::parse(Rule::multi_comment, "/* bad comment"); + assert!(parse.is_err()); + } + + #[test] + fn single_comment() { + let parse = Foam::parse(Rule::single_comment, "// this is comment"); + assert!(parse.is_ok()); + } + + #[test] + fn chained_comments() { + let text = "/* this is one comment */ +// And this is another"; + let parse = Foam::parse(Rule::file, text); + assert!(parse.is_ok(), "{:?}", parse); + } + + #[test] + fn identifier() { + let parse = Foam::parse(Rule::identifier, "FoamFile"); + assert!(parse.is_ok()); + let parse = Foam::parse(Rule::identifier, "foam_file"); + assert!(parse.is_ok()); + } + + #[test] + fn broken_identifer() { + let parse = Foam::parse(Rule::identifier, "123"); + assert!(parse.is_err()); + + let parse = Foam::parse(Rule::identifier, "asd "); + assert!(parse.is_ok(), "{:?}", parse); + // XXX check if the identifier lost its space. + } + + #[test] + fn attribution() { + let parse = Foam::parse(Rule::attribution, "version 2.0;"); + assert!(parse.is_ok(), "{:?}", parse); + } + + #[test] + fn broken_attribution() { + let parse = Foam::parse(Rule::attribution, "version 2.0"); + assert!(parse.is_err(), "{:?}", parse); + } + + #[test] + fn dictionary() { + let text = "FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location system; + object caseSetupDict; +}"; + let parse = Foam::parse(Rule::dictionary, text); + assert!(parse.is_ok(), "{:#?}", parse); + } + + #[test] + fn dict_in_dict() { + let text = "dict1 { dict2 { class bad; } }"; + let parse = Foam::parse(Rule::dictionary, text); + assert!(parse.is_err(), "{:#?}", parse); + } +} diff --git a/pestfoamtest/src/main.rs b/pestfoamtest/src/main.rs deleted file mode 100644 index c8b571b..0000000 --- a/pestfoamtest/src/main.rs +++ /dev/null @@ -1,15 +0,0 @@ -use pest::Parser; -use pest_derive::Parser; - -#[derive(Parser)] -#[grammar = "foam.pest"] -pub struct Foam; - -fn main() { - let parse = Foam::parse(Rule::multi_comment, "/* this is comment */"); - println!("{:?}", parse); - let parse = Foam::parse(Rule::single_comment, "// this is comment"); - println!("{:?}", parse); - let parse = Foam::parse(Rule::field, "-273.15"); - println!("{:?}", parse); -}