From 6bcfa3c8555a48a9dc1ebff765e8e9f58f8acabc Mon Sep 17 00:00:00 2001 From: Daniel Voogsgerd Date: Mon, 24 Mar 2025 12:29:38 +0100 Subject: [PATCH 1/2] tests(dsl): Use snapshot testing for BraneScript and Bakery Also moved these integration tests to the correct location for integration tests --- Cargo.lock | 27 ++++++++++++++ brane-dsl/Cargo.toml | 3 ++ brane-dsl/src/compiler.rs | 65 ---------------------------------- brane-dsl/tests/bakery.rs | 22 ++++++++++++ brane-dsl/tests/branescript.rs | 23 ++++++++++++ 5 files changed, 75 insertions(+), 65 deletions(-) create mode 100644 brane-dsl/tests/bakery.rs create mode 100644 brane-dsl/tests/branescript.rs diff --git a/Cargo.lock b/Cargo.lock index 6050bdfb..468ada31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -763,6 +763,7 @@ version = "3.0.0" dependencies = [ "brane-shr 3.0.0", "enum-debug", + "insta", "log", "nom", "nom_locate", @@ -2660,6 +2661,20 @@ dependencies = [ "web-time", ] +[[package]] +name = "insta" +version = "1.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50259abbaa67d11d2bcafc7ba1d094ed7a0c70e3ce893f0d0997f73558cb3084" +dependencies = [ + "console", + "linked-hash-map", + "once_cell", + "pin-project", + "serde", + "similar", +] + [[package]] name = "ipnet" version = "2.11.0" @@ -2860,6 +2875,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "linux-raw-sys" version = "0.9.2" @@ -4287,6 +4308,12 @@ dependencies = [ "libc", ] +[[package]] +name = "similar" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" + [[package]] name = "simple_asn1" version = "0.6.3" diff --git a/brane-dsl/Cargo.toml b/brane-dsl/Cargo.toml index 591f8bee..0109c36f 100644 --- a/brane-dsl/Cargo.toml +++ b/brane-dsl/Cargo.toml @@ -19,5 +19,8 @@ serde = "1.0.204" brane-shr = { path = "../brane-shr" } specifications = { path = "../specifications" } +[dev-dependencies] +insta = { version = "1.42.2", features=["yaml"] } + [lints] workspace = true diff --git a/brane-dsl/src/compiler.rs b/brane-dsl/src/compiler.rs index 14fe6255..eb81b58e 100644 --- a/brane-dsl/src/compiler.rs +++ b/brane-dsl/src/compiler.rs @@ -26,71 +26,6 @@ use crate::scanner::{self, Span, Token, Tokens}; use crate::spec::Language; -/***** TESTS *****/ -#[cfg(test)] -pub mod tests { - use brane_shr::utilities::{create_package_index, test_on_dsl_files}; - - use super::*; - - - /// Tests BraneScript files. - #[test] - fn test_bscript() { - // Simply pass to the compiler - test_on_dsl_files("BraneScript", |path, code| { - // Print the header always - println!("{}", (0..80).map(|_| '-').collect::()); - println!("File '{}' gave us:", path.display()); - - // Read the package index - let pindex: PackageIndex = create_package_index(); - - // Create a compiler and compile it; - let res: Program = match parse(code, &pindex, &ParserOptions::bscript()) { - Ok(res) => res, - Err(err) => { - panic!("Failed to parse BraneScript file '{}': {}", path.display(), err); - }, - }; - - // Print it for good measure - println!("{res:#?}"); - println!("{}\n\n", (0..80).map(|_| '-').collect::()); - }); - } - - /// Tests Bakery files. - #[test] - fn test_bakery() { - // Simply pass to the compiler - test_on_dsl_files("Bakery", |path, code| { - // Print the header always - println!("{}", (0..80).map(|_| '-').collect::()); - println!("File '{}' gave us:", path.display()); - - // Read the package index - let pindex: PackageIndex = create_package_index(); - - // Create a compiler and compile it; - let res: Program = match parse(code, &pindex, &ParserOptions::bakery()) { - Ok(res) => res, - Err(err) => { - panic!("Failed to parse Bakery file '{}': {}", path.display(), err); - }, - }; - - // Print it for good measure - println!("{res:#?}"); - println!("{}\n\n", (0..80).map(|_| '-').collect::()); - }); - } -} - - - - - /***** AUXILLARY STRUCTS *****/ /// Defines options that configure the compiler before we use it. #[derive(Clone, Debug)] diff --git a/brane-dsl/tests/bakery.rs b/brane-dsl/tests/bakery.rs new file mode 100644 index 00000000..f53e562b --- /dev/null +++ b/brane-dsl/tests/bakery.rs @@ -0,0 +1,22 @@ +use brane_dsl::{ParserOptions, parse}; +use brane_shr::utilities::{create_package_index, test_on_dsl_files}; + +/// Tests Bakery files. +#[test] +fn test_bakery() { + // Simply pass to the compiler + test_on_dsl_files("Bakery", |path, code| { + // Read the package index + let pindex = create_package_index(); + + // Create a compiler and compile it; + let res = match parse(code, &pindex, &ParserOptions::bakery()) { + Ok(res) => res, + Err(err) => { + panic!("Failed to parse Bakery file '{}': {}", path.display(), err); + }, + }; + + insta::assert_debug_snapshot!(path.as_os_str().to_str().expect("Invalid test name"), res); + }); +} diff --git a/brane-dsl/tests/branescript.rs b/brane-dsl/tests/branescript.rs new file mode 100644 index 00000000..638e8ccd --- /dev/null +++ b/brane-dsl/tests/branescript.rs @@ -0,0 +1,23 @@ +use brane_dsl::{ParserOptions, parse}; +use brane_shr::utilities::{create_package_index, test_on_dsl_files}; + + +/// Tests BraneScript files. +#[test] +fn test_bscript() { + // Simply pass to the compiler + test_on_dsl_files("BraneScript", |path, code| { + // Read the package index + let pindex = create_package_index(); + + // Create a compiler and compile it; + let res = match parse(code, &pindex, &ParserOptions::bscript()) { + Ok(res) => res, + Err(err) => { + panic!("Failed to parse BraneScript file '{}': {}", path.display(), err); + }, + }; + + insta::assert_debug_snapshot!(path.as_os_str().to_str().expect("Invalid test name"), res); + }); +} From 9c7b7ea5980d0309ffa4647da3a9fa68f7a1a67e Mon Sep 17 00:00:00 2001 From: Daniel Voogsgerd Date: Wed, 19 Mar 2025 11:25:58 +0100 Subject: [PATCH 2/2] chore(deps): Bump nom to version 8 --- Cargo.lock | 48 +++++- brane-dsl/Cargo.toml | 5 +- brane-dsl/src/compiler.rs | 24 +-- brane-dsl/src/errors.rs | 2 +- brane-dsl/src/parser/bakery.rs | 267 ----------------------------- brane-dsl/src/parser/bscript.rs | 5 +- brane-dsl/src/parser/expression.rs | 2 +- brane-dsl/src/parser/instance.rs | 6 +- brane-dsl/src/parser/mod.rs | 1 - brane-dsl/src/scanner/literal.rs | 6 +- brane-dsl/src/scanner/scanning.rs | 7 +- brane-dsl/src/scanner/tokens.rs | 88 +++++----- 12 files changed, 105 insertions(+), 356 deletions(-) delete mode 100644 brane-dsl/src/parser/bakery.rs diff --git a/Cargo.lock b/Cargo.lock index 468ada31..15ab0782 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -148,7 +148,7 @@ dependencies = [ "asn1-rs-derive", "asn1-rs-impl", "displaydoc", - "nom", + "nom 7.1.3", "num-traits", "rusticata-macros", "thiserror 2.0.12", @@ -765,8 +765,9 @@ dependencies = [ "enum-debug", "insta", "log", - "nom", - "nom_locate", + "nom 8.0.0", + "nom-language", + "nom_locate 5.0.0", "rand 0.9.0", "regex", "serde", @@ -782,8 +783,8 @@ dependencies = [ "bytes", "enum-debug", "log", - "nom", - "nom_locate", + "nom 7.1.3", + "nom_locate 4.2.0", "rand 0.8.5", "regex", "semver", @@ -1393,7 +1394,7 @@ checksum = "07da5016415d5a3c4dd39b11ed26f915f52fc4e0dc197d87908bc916e51bc1a6" dependencies = [ "asn1-rs", "displaydoc", - "nom", + "nom 7.1.3", "num-bigint", "num-traits", "rusticata-macros", @@ -3095,6 +3096,24 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nom" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" +dependencies = [ + "memchr", +] + +[[package]] +name = "nom-language" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2de2bc5b451bfedaef92c90b8939a8fff5770bdcc1fafd6239d086aab8fa6b29" +dependencies = [ + "nom 8.0.0", +] + [[package]] name = "nom_locate" version = "4.2.0" @@ -3103,7 +3122,18 @@ checksum = "1e3c83c053b0713da60c5b8de47fe8e494fe3ece5267b2f23090a07a053ba8f3" dependencies = [ "bytecount", "memchr", - "nom", + "nom 7.1.3", +] + +[[package]] +name = "nom_locate" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b577e2d69827c4740cba2b52efaad1c4cc7c73042860b199710b3575c68438d" +dependencies = [ + "bytecount", + "memchr", + "nom 8.0.0", ] [[package]] @@ -3878,7 +3908,7 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" dependencies = [ - "nom", + "nom 7.1.3", ] [[package]] @@ -5814,7 +5844,7 @@ dependencies = [ "data-encoding", "der-parser", "lazy_static", - "nom", + "nom 7.1.3", "oid-registry", "rusticata-macros", "thiserror 2.0.12", diff --git a/brane-dsl/Cargo.toml b/brane-dsl/Cargo.toml index 0109c36f..e87ad0be 100644 --- a/brane-dsl/Cargo.toml +++ b/brane-dsl/Cargo.toml @@ -10,8 +10,9 @@ license.workspace = true [dependencies] enum-debug.workspace = true log = "0.4.22" -nom = "7.1.0" -nom_locate = "4.1.0" +nom = "8.0.0" +nom_locate = "5.0.0" +nom-language = "0.1.0" rand = "0.9.0" regex = "1.5.0" serde = "1.0.204" diff --git a/brane-dsl/src/compiler.rs b/brane-dsl/src/compiler.rs index eb81b58e..5392e070 100644 --- a/brane-dsl/src/compiler.rs +++ b/brane-dsl/src/compiler.rs @@ -14,14 +14,14 @@ // use log::trace; -use nom::InputLength; -use nom::error::VerboseErrorKind; +use nom::Input as _; +use nom_language::error::VerboseErrorKind; use specifications::package::PackageIndex; use crate::errors; pub use crate::errors::ParseError as Error; use crate::parser::ast::Program; -use crate::parser::{bakery, bscript}; +use crate::parser::bscript; use crate::scanner::{self, Span, Token, Tokens}; use crate::spec::Language; @@ -80,7 +80,7 @@ impl ParserOptions { /// /// # Errors /// This function may error if we could not read the reader or if the source code was somehow malformed. -pub fn parse>(source: S, pindex: &PackageIndex, options: &ParserOptions) -> Result { +pub fn parse>(source: S, _pindex: &PackageIndex, options: &ParserOptions) -> Result { let source: &str = source.as_ref(); // Run that through the scanner @@ -117,21 +117,11 @@ pub fn parse>(source: S, pindex: &PackageIndex, options: &ParserOp }, }, - Language::Bakery => match bakery::parse_ast(tks, pindex.clone()) { - Ok(ast) => ast, - - Err(nom::Err::Error(e)) | Err(nom::Err::Failure(e)) => { - // Match the EOF-error - if e.errors[0].1 == VerboseErrorKind::Nom(nom::error::ErrorKind::Eof) { - return Err(Error::Eof { lang: Language::BraneScript, err: errors::convert_parser_error(tks, e) }); - } - return Err(Error::ParseError { lang: Language::Bakery, err: errors::convert_parser_error(tks, e) }); - }, - Err(err) => { - return Err(Error::ParserError { lang: Language::Bakery, err: format!("{err}") }); - }, + Language::Bakery => { + todo!("Support for the bakery language was removed as it was not functional anymore, this might be added back later"); }, }; + if remain.input_len() > 0 { return Err(Error::LeftoverTokensError { lang: options.lang }); } diff --git a/brane-dsl/src/errors.rs b/brane-dsl/src/errors.rs index 85f298cb..000e4fbd 100644 --- a/brane-dsl/src/errors.rs +++ b/brane-dsl/src/errors.rs @@ -16,7 +16,7 @@ use std::error::Error; use std::fmt::{Display, Formatter, Result as FResult}; -use nom::error::{VerboseError, VerboseErrorKind}; +use nom_language::error::{VerboseError, VerboseErrorKind}; use crate::scanner::{Span, Tokens}; use crate::spec::{Language, TextRange}; diff --git a/brane-dsl/src/parser/bakery.rs b/brane-dsl/src/parser/bakery.rs deleted file mode 100644 index 672064df..00000000 --- a/brane-dsl/src/parser/bakery.rs +++ /dev/null @@ -1,267 +0,0 @@ -// use super::ast::{Expr, Ident, Operator, Stmt, UnOp}; -// use crate::parser::{identifier, literal, operator, pattern}; -// use crate::scanner::{Token, Tokens}; -// use crate::tag_token; -// use nom::{branch, combinator as comb, multi, sequence as seq}; -// use nom::{ -// error::{ContextError, ErrorKind, ParseError, VerboseError}, -// Needed, -// }; -// use nom::{IResult, Parser}; -use std::collections::HashSet; - -use nom::IResult; -use nom::error::VerboseError; -use specifications::package::PackageIndex; - -use super::ast::{Block, Expr, Literal, Program, Stmt}; -use crate::scanner::Tokens; -use crate::spec::TextRange; -// use std::num::NonZeroUsize; - -pub fn parse_ast(_input: Tokens, _package_index: PackageIndex) -> IResult> { - // For now, let's be really naive - Ok((Tokens::new(&[]), Program { - block: Block::new( - vec![Stmt::new_expr(Expr::Literal { literal: Literal::String { value: "".into(), range: TextRange::none() } }, TextRange::none())], - TextRange::none(), - ), - metadata: HashSet::new(), - })) - // comb::all_consuming(multi::many0(parse_stmt)) - // .parse(input) - // .map(|(tokens, program)| { - // let program = pattern::resolve_patterns(program, &package_index) - // .map_err(|_| nom::Err::Incomplete(Needed::Size(NonZeroUsize::new(1).unwrap())))?; - - // Ok((tokens, program)) - // })? -} - -// /// -// /// -// /// -// pub fn parse_stmt<'a, E: ParseError> + ContextError>>( -// input: Tokens<'a> -// ) -> IResult { -// if input.tok.is_empty() { -// return Err(nom::Err::Error(nom::error_position!(input, ErrorKind::Tag))); -// } - -// branch::alt((import_stmt, assign_stmt, return_stmt, expr_stmt)).parse(input) -// } - -// /// -// /// -// /// -// pub fn assign_stmt<'a, E: ParseError> + ContextError>>( -// input: Tokens<'a> -// ) -> IResult { -// comb::map( -// seq::terminated( -// seq::separated_pair(identifier::parse, tag_token!(Token::Assign), expr), -// comb::cut(tag_token!(Token::Semicolon)), -// ), -// |(ident, expr)| Stmt::Assign(ident, expr), -// ) -// .parse(input) -// } - -// /// -// /// -// /// -// pub fn import_stmt<'a, E: ParseError> + ContextError>>( -// input: Tokens<'a> -// ) -> IResult { -// nom::error::context( -// "'import' statement", -// comb::map( -// seq::preceded( -// tag_token!(Token::Import), -// comb::cut(seq::terminated( -// seq::pair( -// identifier::parse, -// comb::opt(multi::many0(seq::preceded(tag_token!(Token::Comma), identifier::parse))), -// ), -// tag_token!(Token::Semicolon), -// )), -// ), -// |(package, packages)| { -// let mut packages: Vec = packages.unwrap_or_default(); -// packages.insert(0, package); -// packages.dedup_by(|Ident(a), Ident(b)| a.eq_ignore_ascii_case(b)); - -// let imports = packages -// .into_iter() -// .map(|package| Stmt::Import { package, version: None }) -// .collect(); - -// Stmt::Block(imports) -// }, -// ), -// ) -// .parse(input) -// } - -// /// -// /// -// /// -// pub fn return_stmt<'a, E: ParseError> + ContextError>>( -// input: Tokens<'a> -// ) -> IResult { -// comb::map( -// seq::delimited( -// tag_token!(Token::Return), -// comb::opt(expr), -// comb::cut(tag_token!(Token::Semicolon)), -// ), -// Stmt::Return, -// ) -// .parse(input) -// } - -// /// -// /// -// /// -// pub fn expr_stmt<'a, E: ParseError> + ContextError>>( -// input: Tokens<'a> -// ) -> IResult { -// comb::map(seq::terminated(expr, comb::cut(tag_token!(Token::Semicolon))), |e| { -// Stmt::Expr(e) -// }) -// .parse(input) -// } - -// /// -// /// -// /// -// pub fn expr<'a, E: ParseError> + ContextError>>(input: Tokens<'a>) -> IResult { -// expr_pratt(input, 0) -// } - -// /// -// /// -// /// -// fn expr_pratt<'a, E: ParseError> + ContextError>>( -// input: Tokens<'a>, -// min_bp: u8, -// ) -> IResult { -// let (mut remainder, mut lhs) = match operator::unary_operator::(input) { -// Ok((r, UnOp::Idx)) => { -// let (r2, entries) = seq::terminated( -// comb::opt(seq::terminated( -// seq::pair(expr, multi::many0(seq::preceded(tag_token!(Token::Comma), expr))), -// comb::opt(tag_token!(Token::Comma)), -// )), -// tag_token!(Token::RightBracket), -// ) -// .parse(r)?; - -// let expr = if let Some((head, entries)) = entries { -// let e = [&[head], &entries[..]].concat().to_vec(); - -// Expr::Array(e) -// } else { -// Expr::Array(vec![]) -// }; - -// (r2, expr) -// } -// Ok((r, UnOp::Prio)) => seq::terminated(expr, tag_token!(Token::RightParen)).parse(r)?, -// Ok((r, operator)) => { -// let (_, r_bp) = operator.binding_power(); -// let (r, rhs) = expr_pratt(r, r_bp)?; - -// ( -// r, -// Expr::Unary { -// operator, -// operand: Box::new(rhs), -// }, -// ) -// } -// _ => expr_atom(input)?, -// }; - -// loop { -// // Append any subsequent atoms to LHS. -// // The LHS will be turned into a pattern expression. -// if let Ok((r, ident)) = expr_atom::(remainder) { -// let terms = match lhs { -// Expr::Pattern(terms) => { -// let mut terms = terms; -// terms.push(ident); - -// terms -// } -// current => { -// vec![current, ident] -// } -// }; - -// lhs = Expr::Pattern(terms); - -// remainder = r; -// continue; -// } - -// // -// // -// // -// match operator::parse::(remainder) { -// Ok((r, Operator::Binary(operator))) => { -// let (left_bp, right_bp) = operator.binding_power(); -// if left_bp < min_bp { -// break; -// } - -// // Recursive until lower binding power is encountered. -// let (remainder_3, rhs) = expr_pratt(r, right_bp)?; - -// remainder = remainder_3; -// lhs = Expr::Binary { -// operator, -// lhs_operand: Box::new(lhs), -// rhs_operand: Box::new(rhs), -// }; -// } -// Ok((r, Operator::Unary(operator))) => { -// let (left_bp, _) = operator.binding_power(); -// if left_bp < min_bp { -// break; -// } - -// lhs = if let UnOp::Idx = operator { -// let (r2, rhs) = seq::terminated(expr, tag_token!(Token::RightBracket)).parse(r)?; -// remainder = r2; - -// Expr::Index { -// array: Box::new(lhs), -// index: Box::new(rhs), -// } -// } else { -// Expr::Unary { -// operator, -// operand: Box::new(lhs), -// } -// }; -// } -// _ => break, -// } -// } - -// Ok((remainder, lhs)) -// } - -// /// -// /// -// /// -// pub fn expr_atom<'a, E: ParseError> + ContextError>>( -// input: Tokens<'a> -// ) -> IResult { -// branch::alt(( -// comb::map(literal::parse, Expr::Literal), -// comb::map(identifier::parse, Expr::Ident), -// )) -// .parse(input) -// } diff --git a/brane-dsl/src/parser/bscript.rs b/brane-dsl/src/parser/bscript.rs index e2327277..179b3050 100644 --- a/brane-dsl/src/parser/bscript.rs +++ b/brane-dsl/src/parser/bscript.rs @@ -17,8 +17,9 @@ use std::collections::HashSet; use std::num::NonZeroUsize; use log::trace; -use nom::error::{ContextError, ErrorKind, ParseError, VerboseError}; +use nom::error::{ContextError, ErrorKind, ParseError}; use nom::{IResult, Parser, branch, combinator as comb, multi, sequence as seq}; +use nom_language::error::VerboseError; use super::ast::{Block, Identifier, Literal, Node, Program, Property, Stmt}; use crate::ast::Attribute; @@ -147,7 +148,7 @@ pub fn parse_ast(input: Tokens) -> IResult trace!("Attempting to parse BraneScript AST"); // Parse it all as statements - let (r, stmts) = comb::all_consuming(multi::many0(parse_stmt))(input)?; + let (r, stmts) = comb::all_consuming(multi::many0(parse_stmt)).parse(input)?; // Wrap it in a program and done let start_pos: TextPos = stmts.first().map(|s| s.start().clone()).unwrap_or(TextPos::none()); diff --git a/brane-dsl/src/parser/expression.rs b/brane-dsl/src/parser/expression.rs index 973c29b4..d9792ce6 100644 --- a/brane-dsl/src/parser/expression.rs +++ b/brane-dsl/src/parser/expression.rs @@ -258,7 +258,7 @@ fn proj_expr<'a, E: ParseError> + ContextError>>(input: To /// This function returns a nom::Error if it failed to parse an expression. fn array_expr<'a, 'b, E: ParseError> + ContextError>>( start_range: &'b Option, -) -> impl 'b + Parser, Expr, E> { +) -> impl 'b + Parser, Output = Expr, Error = E> { trace!("Attempting to parse Array-expression"); // Return a closure that does the actual thingy diff --git a/brane-dsl/src/parser/instance.rs b/brane-dsl/src/parser/instance.rs index 398003da..70722a36 100644 --- a/brane-dsl/src/parser/instance.rs +++ b/brane-dsl/src/parser/instance.rs @@ -63,11 +63,13 @@ pub fn parse<'a, E: ParseError> + ContextError>>(input: To // Get the new token first let (r, n): (Tokens<'a>, Tokens<'a>) = tag_token!(Token::New)(input)?; + // Parse the main body let (r, (class, properties)): (Tokens<'a>, (Identifier, Option>)) = - comb::cut(seq::pair(identifier::parse, seq::preceded(tag_token!(Token::LeftBrace), comb::opt(multi::many1(instance_property)))))(r)?; + comb::cut(seq::pair(identifier::parse, seq::preceded(tag_token!(Token::LeftBrace), comb::opt(multi::many1(instance_property))))).parse(r)?; + // Parse the closing bracket - let (r, b): (Tokens<'a>, Tokens<'a>) = comb::cut(tag_token!(Token::RightBrace))(r)?; + let (r, b): (Tokens<'a>, Tokens<'a>) = comb::cut(tag_token!(Token::RightBrace)).parse(r)?; // Now put that in an Expr and return Ok((r, Expr::new_instance(class, properties.unwrap_or_default(), TextRange::from((n.tok[0].inner(), b.tok[0].inner()))))) diff --git a/brane-dsl/src/parser/mod.rs b/brane-dsl/src/parser/mod.rs index 4afa3c95..e158a000 100644 --- a/brane-dsl/src/parser/mod.rs +++ b/brane-dsl/src/parser/mod.rs @@ -23,7 +23,6 @@ mod operator; // Declare public modules pub mod ast; -pub mod bakery; pub mod bscript; diff --git a/brane-dsl/src/scanner/literal.rs b/brane-dsl/src/scanner/literal.rs index 2916c383..c3cb5f79 100644 --- a/brane-dsl/src/scanner/literal.rs +++ b/brane-dsl/src/scanner/literal.rs @@ -97,7 +97,8 @@ fn string<'a, E: ParseError> + ContextError>>(input: Span<'a>) nom::error::context( "string", seq::preceded(cc::char('\"'), comb::cut(seq::terminated(bc::escaped(bc::is_not("\"\\"), '\\', cc::one_of("\"ntr\\\'")), cc::char('\"')))), - )(input) + ) + .parse(input) } /// Parses a real token off of the head of the given input. @@ -121,7 +122,8 @@ fn real<'a, E: ParseError> + ContextError>>(input: Span<'a>) - integer, ))), comb::recognize(seq::tuple((integer, cc::char('.'), comb::opt(integer)))), - ))(input) + )) + .parse(input) } diff --git a/brane-dsl/src/scanner/scanning.rs b/brane-dsl/src/scanner/scanning.rs index 8ee9a920..7a1ae478 100644 --- a/brane-dsl/src/scanner/scanning.rs +++ b/brane-dsl/src/scanner/scanning.rs @@ -14,8 +14,9 @@ use nom::bytes::complete as bc; use nom::character::complete as cc; -use nom::error::{ContextError, ParseError, VerboseError}; +use nom::error::{ContextError, ParseError}; use nom::{IResult, Parser, branch, combinator as comb, multi, sequence as seq}; +use nom_language::error::VerboseError; use super::tokens::Token; use super::{Span, comments, literal}; @@ -37,7 +38,7 @@ const SEPARATORS: &str = " \n\t\r{}[]()-=+;:'\"\\|/?>.<,`~*&^%$#@!"; /// /// # Returns /// A new function that implements the parser plus the wrapping whitespaces. -fn ws0<'a, O, E: ParseError>, F: Parser, O, E>>(f: F) -> impl Parser, O, E> { +fn ws0<'a, O, E: ParseError>, F: Parser, Output = O, Error = E>>(f: F) -> impl Parser, Output = O, Error = E> { seq::delimited(cc::multispace0, f, cc::multispace0) } @@ -181,7 +182,7 @@ fn identifier<'a, E: ParseError> + ContextError>>(input: Span< /// # Errors /// This function may error if it failed to parse a separator. fn separator<'a, E: ParseError> + ContextError>>(input: Span<'a>) -> IResult, char, E> { - branch::alt((cc::one_of(SEPARATORS), comb::map(comb::eof, |_| '\0')))(input) + branch::alt((cc::one_of(SEPARATORS), comb::map(comb::eof, |_| '\0'))).parse(input) } diff --git a/brane-dsl/src/scanner/tokens.rs b/brane-dsl/src/scanner/tokens.rs index 26f816f7..c3668b09 100644 --- a/brane-dsl/src/scanner/tokens.rs +++ b/brane-dsl/src/scanner/tokens.rs @@ -1,8 +1,7 @@ use std::iter::Enumerate; -use std::ops::{Range, RangeFrom, RangeFull, RangeTo}; use std::str::FromStr; -use nom::{InputIter, InputLength, InputTake, Needed, Slice}; +use nom::{Input, Needed}; type Span<'a> = nom_locate::LocatedSpan<&'a str>; @@ -208,63 +207,28 @@ impl<'a> Tokens<'a> { pub fn new(vec: &'a [Token]) -> Self { Tokens { tok: vec, start: 0, end: vec.len() } } } -impl InputLength for Tokens<'_> { - #[inline] +impl<'a> Input for Tokens<'a> { + type Item = &'a Token<'a>; + type Iter = ::std::slice::Iter<'a, Token<'a>>; + type IterIndices = Enumerate<::std::slice::Iter<'a, Token<'a>>>; + fn input_len(&self) -> usize { self.tok.len() } -} -impl InputTake for Tokens<'_> { - #[inline] fn take(&self, count: usize) -> Self { Tokens { tok: &self.tok[0..count], start: 0, end: count } } - #[inline] + // TODO: This seems new + fn take_from(&self, index: usize) -> Self { + let new = &self.tok[index..]; + Tokens { tok: new, start: 0, end: new.len() } + } + fn take_split(&self, count: usize) -> (Self, Self) { let (prefix, suffix) = self.tok.split_at(count); let first = Tokens { tok: prefix, start: 0, end: prefix.len() }; let second = Tokens { tok: suffix, start: 0, end: suffix.len() }; (second, first) } -} - -impl InputLength for Token<'_> { - #[inline] - fn input_len(&self) -> usize { 1 } -} - -impl Slice> for Tokens<'_> { - #[inline] - fn slice(&self, range: Range) -> Self { - Tokens { tok: self.tok.slice(range.clone()), start: self.start + range.start, end: self.start + range.end } - } -} - -impl Slice> for Tokens<'_> { - #[inline] - fn slice(&self, range: RangeTo) -> Self { self.slice(0..range.end) } -} - -impl Slice> for Tokens<'_> { - #[inline] - fn slice(&self, range: RangeFrom) -> Self { self.slice(range.start..self.end - self.start) } -} - -impl Slice for Tokens<'_> { - #[inline] - fn slice(&self, _: RangeFull) -> Self { Tokens { tok: self.tok, start: self.start, end: self.end } } -} - -impl<'a> InputIter for Tokens<'a> { - type Item = &'a Token<'a>; - type Iter = Enumerate<::std::slice::Iter<'a, Token<'a>>>; - type IterElem = ::std::slice::Iter<'a, Token<'a>>; - - #[inline] - fn iter_indices(&self) -> Enumerate<::std::slice::Iter<'a, Token<'a>>> { self.tok.iter().enumerate() } - #[inline] - fn iter_elements(&self) -> ::std::slice::Iter<'a, Token<'a>> { self.tok.iter() } - - #[inline] fn position

(&self, predicate: P) -> Option where P: Fn(Self::Item) -> bool, @@ -272,8 +236,34 @@ impl<'a> InputIter for Tokens<'a> { self.tok.iter().position(predicate) } - #[inline] + fn iter_elements(&self) -> ::std::slice::Iter<'a, Token<'a>> { self.tok.iter() } + + fn iter_indices(&self) -> Enumerate<::std::slice::Iter<'a, Token<'a>>> { self.tok.iter().enumerate() } + fn slice_index(&self, count: usize) -> Result { if self.tok.len() >= count { Ok(count) } else { Err(Needed::new(count - self.tok.len())) } } } + +// TODO: These impls probably need to go somewhere +// impl Slice> for Tokens<'_> { +// #[inline] +// fn slice(&self, range: Range) -> Self { +// Tokens { tok: self.tok.slice(range.clone()), start: self.start + range.start, end: self.start + range.end } +// } +// } +// +// impl Slice> for Tokens<'_> { +// #[inline] +// fn slice(&self, range: RangeTo) -> Self { self.slice(0..range.end) } +// } +// +// impl Slice> for Tokens<'_> { +// #[inline] +// fn slice(&self, range: RangeFrom) -> Self { self.slice(range.start..self.end - self.start) } +// } +// +// impl Slice for Tokens<'_> { +// #[inline] +// fn slice(&self, _: RangeFull) -> Self { Tokens { tok: self.tok, start: self.start, end: self.end } } +// }