Move sexp into compare.

This commit is contained in:
Tom Alexander 2023-09-11 15:31:48 -04:00
parent 98de5e4ec5
commit a651b79e77
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
8 changed files with 39 additions and 26 deletions

View File

@ -74,7 +74,7 @@ fn write_header(test_file: &mut File) {
use organic::compare_document; use organic::compare_document;
use organic::parser::parse; use organic::parser::parse;
use organic::emacs_parse_anonymous_org_document; use organic::emacs_parse_anonymous_org_document;
use organic::parser::sexp::sexp; use organic::sexp;
"# "#
) )

View File

@ -10,7 +10,7 @@ use organic::emacs_parse_file_org_document;
use organic::get_emacs_version; use organic::get_emacs_version;
use organic::get_org_mode_version; use organic::get_org_mode_version;
use organic::parser::parse_with_settings; use organic::parser::parse_with_settings;
use organic::parser::sexp::sexp; use organic::sexp;
use organic::GlobalSettings; use organic::GlobalSettings;
use organic::LocalFileAccessInterface; use organic::LocalFileAccessInterface;
@ -66,8 +66,7 @@ fn run_anonymous_parse<P: AsRef<str>>(org_contents: P) -> Result<(), Box<dyn std
eprintln!("Using org-mode version: {}", get_org_mode_version()?.trim()); eprintln!("Using org-mode version: {}", get_org_mode_version()?.trim());
let rust_parsed = parse(org_contents)?; let rust_parsed = parse(org_contents)?;
let org_sexp = emacs_parse_anonymous_org_document(org_contents)?; let org_sexp = emacs_parse_anonymous_org_document(org_contents)?;
let (_remaining, parsed_sexp) = let (_remaining, parsed_sexp) = sexp(org_sexp.as_str()).map_err(|e| e.to_string())?;
sexp(org_sexp.as_str()).map_err(|e| e.to_string())?;
println!("{}\n\n\n", org_contents); println!("{}\n\n\n", org_contents);
println!("{}", org_sexp); println!("{}", org_sexp);
@ -103,8 +102,7 @@ fn run_parse_on_file<P: AsRef<Path>>(org_path: P) -> Result<(), Box<dyn std::err
}; };
let rust_parsed = parse_with_settings(org_contents, &global_settings)?; let rust_parsed = parse_with_settings(org_contents, &global_settings)?;
let org_sexp = emacs_parse_file_org_document(org_path)?; let org_sexp = emacs_parse_file_org_document(org_path)?;
let (_remaining, parsed_sexp) = let (_remaining, parsed_sexp) = sexp(org_sexp.as_str()).map_err(|e| e.to_string())?;
sexp(org_sexp.as_str()).map_err(|e| e.to_string())?;
println!("{}\n\n\n", org_contents); println!("{}\n\n\n", org_contents);
println!("{}", org_sexp); println!("{}", org_sexp);

View File

@ -1,11 +1,11 @@
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::collections::HashSet; use std::collections::HashSet;
use super::sexp::unquote;
use super::sexp::Token;
use super::util::assert_bounds; use super::util::assert_bounds;
use super::util::assert_name; use super::util::assert_name;
use super::util::get_property; use super::util::get_property;
use crate::parser::sexp::unquote;
use crate::parser::sexp::Token;
use crate::types::AngleLink; use crate::types::AngleLink;
use crate::types::Bold; use crate::types::Bold;
use crate::types::Citation; use crate::types::Citation;

View File

@ -1,8 +1,10 @@
mod diff; mod diff;
mod parse; mod parse;
mod sexp;
mod util; mod util;
pub use diff::compare_document; pub use diff::compare_document;
pub use parse::emacs_parse_anonymous_org_document; pub use parse::emacs_parse_anonymous_org_document;
pub use parse::emacs_parse_file_org_document; pub use parse::emacs_parse_file_org_document;
pub use parse::get_emacs_version; pub use parse::get_emacs_version;
pub use parse::get_org_mode_version; pub use parse::get_org_mode_version;
pub use sexp::sexp;

View File

@ -16,9 +16,6 @@ use nom::sequence::delimited;
use nom::sequence::preceded; use nom::sequence::preceded;
use nom::sequence::tuple; use nom::sequence::tuple;
use super::org_source::convert_error;
use super::org_source::OrgSource;
use super::util::get_consumed;
use crate::error::Res; use crate::error::Res;
#[derive(Debug)] #[derive(Debug)]
@ -99,6 +96,25 @@ impl<'s> Token<'s> {
} }
} }
/// Check if the child string slice is a slice of the parent string slice.
fn is_slice_of(parent: &str, child: &str) -> bool {
let parent_start = parent.as_ptr() as usize;
let parent_end = parent_start + parent.len();
let child_start = child.as_ptr() as usize;
let child_end = child_start + child.len();
child_start >= parent_start && child_end <= parent_end
}
/// Get a slice of the string that was consumed in a parser using the original input to the parser and the remaining input after the parser.
pub fn get_consumed<'s>(input: &'s str, remaining: &'s str) -> &'s str {
assert!(is_slice_of(input, remaining));
let source = {
let offset = remaining.as_ptr() as usize - input.as_ptr() as usize;
&input[..offset]
};
source.into()
}
pub(crate) fn unquote(text: &str) -> Result<String, Box<dyn std::error::Error>> { pub(crate) fn unquote(text: &str) -> Result<String, Box<dyn std::error::Error>> {
let mut out = String::with_capacity(text.len()); let mut out = String::with_capacity(text.len());
if !text.starts_with(r#"""#) { if !text.starts_with(r#"""#) {
@ -138,21 +154,18 @@ pub(crate) fn unquote(text: &str) -> Result<String, Box<dyn std::error::Error>>
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
pub fn sexp<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { pub fn sexp<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
let (remaining, _) = multispace0(input)?; let (remaining, _) = multispace0(input)?;
let remaining = OrgSource::new(remaining); let (remaining, tkn) = token(remaining).map(|(rem, out)| (Into::<&str>::into(rem), out))?;
let (remaining, tkn) = token(remaining)
.map(|(rem, out)| (Into::<&str>::into(rem), out))
.map_err(convert_error)?;
let (remaining, _) = multispace0(remaining)?; let (remaining, _) = multispace0(remaining)?;
Ok((remaining, tkn)) Ok((remaining, tkn))
} }
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn token<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> { fn token<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
alt((list, vector, atom))(input) alt((list, vector, atom))(input)
} }
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn list<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> { fn list<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
let (remaining, _) = tag("(")(input)?; let (remaining, _) = tag("(")(input)?;
let (remaining, children) = delimited( let (remaining, children) = delimited(
multispace0, multispace0,
@ -164,7 +177,7 @@ fn list<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
} }
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn vector<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> { fn vector<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
let (remaining, _) = tag("[")(input)?; let (remaining, _) = tag("[")(input)?;
let (remaining, children) = delimited( let (remaining, children) = delimited(
multispace0, multispace0,
@ -176,7 +189,7 @@ fn vector<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
} }
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn atom<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> { fn atom<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
not(peek(one_of(")]")))(input)?; not(peek(one_of(")]")))(input)?;
alt(( alt((
text_with_properties, text_with_properties,
@ -187,7 +200,7 @@ fn atom<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
} }
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn unquoted_atom<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> { fn unquoted_atom<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
let (remaining, body) = take_till1(|c| match c { let (remaining, body) = take_till1(|c| match c {
' ' | '\t' | '\r' | '\n' | ')' | ']' => true, ' ' | '\t' | '\r' | '\n' | ')' | ']' => true,
_ => false, _ => false,
@ -196,7 +209,7 @@ fn unquoted_atom<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
} }
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn quoted_atom<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> { fn quoted_atom<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
let (remaining, _) = tag(r#"""#)(input)?; let (remaining, _) = tag(r#"""#)(input)?;
let (remaining, _) = escaped( let (remaining, _) = escaped(
take_till1(|c| match c { take_till1(|c| match c {
@ -212,7 +225,7 @@ fn quoted_atom<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
} }
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn hash_notation<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> { fn hash_notation<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
let (remaining, _) = tag("#<")(input)?; let (remaining, _) = tag("#<")(input)?;
let (remaining, _body) = take_till1(|c| match c { let (remaining, _body) = take_till1(|c| match c {
'>' => true, '>' => true,
@ -223,7 +236,7 @@ fn hash_notation<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> {
Ok((remaining, Token::Atom(source.into()))) Ok((remaining, Token::Atom(source.into())))
} }
fn text_with_properties<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, Token<'s>> { fn text_with_properties<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
let (remaining, _) = tag("#(")(input)?; let (remaining, _) = tag("#(")(input)?;
let (remaining, (text, props)) = delimited( let (remaining, (text, props)) = delimited(
multispace0, multispace0,

View File

@ -1,4 +1,4 @@
use crate::parser::sexp::Token; use super::sexp::Token;
use crate::types::Source; use crate::types::Source;
/// Check if the child string slice is a slice of the parent string slice. /// Check if the child string slice is a slice of the parent string slice.

View File

@ -15,6 +15,8 @@ pub use compare::emacs_parse_file_org_document;
pub use compare::get_emacs_version; pub use compare::get_emacs_version;
#[cfg(feature = "compare")] #[cfg(feature = "compare")]
pub use compare::get_org_mode_version; pub use compare::get_org_mode_version;
#[cfg(feature = "compare")]
pub use compare::sexp;
mod context; mod context;
mod error; mod error;

View File

@ -37,8 +37,6 @@ mod property_drawer;
mod radio_link; mod radio_link;
mod regular_link; mod regular_link;
mod section; mod section;
#[cfg(feature = "compare")]
pub mod sexp;
mod statistics_cookie; mod statistics_cookie;
mod subscript_and_superscript; mod subscript_and_superscript;
mod table; mod table;