Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make tracking for better error details optional (fixes #1009) #1013

Merged
merged 3 commits into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions debugger/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "pest_debugger"
description = "pest grammar debugger"
version = "2.7.9"
version = "2.7.10"
edition = "2021"
authors = [
"Dragoș Tiselice <[email protected]>",
Expand All @@ -17,9 +17,9 @@ readme = "_README.md"
rust-version = "1.61"

[dependencies]
pest = { path = "../pest", version = "2.7.9" }
pest_meta = { path = "../meta", version = "2.7.9" }
pest_vm = { path = "../vm", version = "2.7.9" }
pest = { path = "../pest", version = "2.7.10" }
pest_meta = { path = "../meta", version = "2.7.10" }
pest_vm = { path = "../vm", version = "2.7.10" }
reqwest = { version = "= 0.11.13", default-features = false, features = [
"blocking",
"json",
Expand Down
6 changes: 3 additions & 3 deletions derive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "pest_derive"
description = "pest's derive macro"
version = "2.7.9"
version = "2.7.10"
edition = "2021"
authors = ["Dragoș Tiselice <[email protected]>"]
homepage = "https://pest.rs/"
Expand All @@ -25,5 +25,5 @@ grammar-extras = ["pest_generator/grammar-extras"]

[dependencies]
# for tests, included transitively anyway
pest = { path = "../pest", version = "2.7.9", default-features = false }
pest_generator = { path = "../generator", version = "2.7.9", default-features = false }
pest = { path = "../pest", version = "2.7.10", default-features = false }
pest_generator = { path = "../generator", version = "2.7.10", default-features = false }
6 changes: 3 additions & 3 deletions generator/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "pest_generator"
description = "pest code generator"
version = "2.7.9"
version = "2.7.10"
edition = "2021"
authors = ["Dragoș Tiselice <[email protected]>"]
homepage = "https://pest.rs/"
Expand All @@ -22,8 +22,8 @@ grammar-extras = ["pest_meta/grammar-extras"]
export-internal = []

[dependencies]
pest = { path = "../pest", version = "2.7.9", default-features = false }
pest_meta = { path = "../meta", version = "2.7.9" }
pest = { path = "../pest", version = "2.7.10", default-features = false }
pest_meta = { path = "../meta", version = "2.7.10" }
proc-macro2 = "1.0"
quote = "1.0"
syn = "2.0"
6 changes: 3 additions & 3 deletions grammars/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "pest_grammars"
description = "pest popular grammar implementations"
version = "2.7.9"
version = "2.7.10"
edition = "2021"
authors = ["Dragoș Tiselice <[email protected]>"]
homepage = "https://pest.rs/"
Expand All @@ -14,8 +14,8 @@ readme = "_README.md"
rust-version = "1.61"

[dependencies]
pest = { path = "../pest", version = "2.7.9" }
pest_derive = { path = "../derive", version = "2.7.9" }
pest = { path = "../pest", version = "2.7.10" }
pest_derive = { path = "../derive", version = "2.7.10" }

[dev-dependencies]
criterion = "0.5"
Expand Down
2 changes: 2 additions & 0 deletions grammars/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ mod tests {

#[test]
fn sql_parse_attempts_error() {
pest::set_error_detail(true);

fn is_whitespace(string: String) -> bool {
string == "\r\n"
|| (string.len() == 1 && string.chars().next().unwrap().is_whitespace())
Expand Down
4 changes: 2 additions & 2 deletions meta/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "pest_meta"
description = "pest meta language parser and validator"
version = "2.7.9"
version = "2.7.10"
edition = "2021"
authors = ["Dragoș Tiselice <[email protected]>"]
homepage = "https://pest.rs/"
Expand All @@ -22,7 +22,7 @@ include = [
rust-version = "1.61"

[dependencies]
pest = { path = "../pest", version = "2.7.9" }
pest = { path = "../pest", version = "2.7.10" }
once_cell = "1.8.0"

[build-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion pest/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "pest"
description = "The Elegant Parser"
version = "2.7.9"
version = "2.7.10"
edition = "2021"
authors = ["Dragoș Tiselice <[email protected]>"]
homepage = "https://pest.rs/"
Expand Down
3 changes: 2 additions & 1 deletion pest/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,8 @@ extern crate std;

pub use crate::parser::Parser;
pub use crate::parser_state::{
set_call_limit, state, Atomicity, Lookahead, MatchDir, ParseResult, ParserState,
set_call_limit, set_error_detail, state, Atomicity, Lookahead, MatchDir, ParseResult,
ParserState,
};
pub use crate::position::Position;
pub use crate::span::{merge_spans, Lines, LinesSpan, Span};
Expand Down
96 changes: 67 additions & 29 deletions pest/src/parser_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use alloc::vec::Vec;
use core::fmt::{Debug, Display, Formatter};
use core::num::NonZeroUsize;
use core::ops::Range;
use core::sync::atomic::{AtomicUsize, Ordering};
use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};

use crate::error::{Error, ErrorVariant};
use crate::iterators::pairs::new;
Expand Down Expand Up @@ -103,6 +103,22 @@ pub fn set_call_limit(limit: Option<NonZeroUsize>) {
CALL_LIMIT.store(limit.map(|f| f.get()).unwrap_or(0), Ordering::Relaxed);
}

static ERROR_DETAIL: AtomicBool = AtomicBool::new(false);

/// Sets whether information for more error details
/// should be collected. This is useful for debugging
/// parser errors (as it leads to more comphrensive
tomtau marked this conversation as resolved.
Show resolved Hide resolved
/// error messages), but it has a higher performance cost.
/// (hence, it's off by default)
///
/// # Arguments
///
/// * `enabled` - Whether to enable the collection for
/// more error details.
pub fn set_error_detail(enabled: bool) {
ERROR_DETAIL.store(enabled, Ordering::Relaxed);
}

#[derive(Debug)]
struct CallLimitTracker {
current_call_limit: Option<(usize, usize)>,
Expand Down Expand Up @@ -204,6 +220,8 @@ impl Display for ParsingToken {
/// The intuition is such rules will be most likely the query user initially wanted to write.
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct ParseAttempts<R> {
/// Indicates whether the parsing attempts are tracked.
enabled: bool,
/// Vec of rule calls sequences awaiting tokens at the same `max_position`.
/// If there are several stacks in vec, it means all those rule stacks are "equal"
/// because their attempts occurred on the same position.
Expand All @@ -227,6 +245,7 @@ impl<R: RuleType> ParseAttempts<R> {
expected_tokens: Vec::with_capacity(EXPECTED_TOKENS_INITIAL_CAPACITY),
unexpected_tokens: Vec::with_capacity(EXPECTED_TOKENS_INITIAL_CAPACITY),
max_position: 0,
enabled: ERROR_DETAIL.load(Ordering::Relaxed),
}
}

Expand Down Expand Up @@ -461,11 +480,18 @@ where
}
};

Err(Error::new_from_pos_with_parsing_attempts(
variant,
Position::new_internal(input, state.attempt_pos),
state.parse_attempts.clone(),
))
if state.parse_attempts.enabled {
Err(Error::new_from_pos_with_parsing_attempts(
variant,
Position::new_internal(input, state.attempt_pos),
state.parse_attempts.clone(),
))
} else {
Err(Error::new_from_pos(
variant,
Position::new_internal(input, state.attempt_pos),
))
}
}
}
}
Expand Down Expand Up @@ -675,7 +701,9 @@ impl<'i, R: RuleType> ParserState<'i, R> {
// Note, that we need to count positive parsing results too, because we can fail in
// optional rule call inside which may lie the farthest
// parsed token.
try_add_rule_to_stack(&mut new_state);
if new_state.parse_attempts.enabled {
try_add_rule_to_stack(&mut new_state);
}
Ok(new_state)
}
Err(mut new_state) => {
Expand All @@ -687,7 +715,9 @@ impl<'i, R: RuleType> ParserState<'i, R> {
neg_attempts_index,
attempts,
);
try_add_rule_to_stack(&mut new_state);
if new_state.parse_attempts.enabled {
try_add_rule_to_stack(&mut new_state);
}
}

if new_state.lookahead == Lookahead::None
Expand Down Expand Up @@ -981,13 +1011,15 @@ impl<'i, R: RuleType> ParserState<'i, R> {
where
F: FnOnce(char) -> bool,
{
let token = ParsingToken::BuiltInRule;
let start_position = self.position.pos();
if self.position.match_char_by(f) {
self.handle_token_parse_result(start_position, token, true);
let succeeded = self.position.match_char_by(f);
if self.parse_attempts.enabled {
let token = ParsingToken::BuiltInRule;
self.handle_token_parse_result(start_position, token, succeeded);
}
if succeeded {
Ok(self)
} else {
self.handle_token_parse_result(start_position, token, false);
Err(self)
}
}
Expand Down Expand Up @@ -1016,15 +1048,17 @@ impl<'i, R: RuleType> ParserState<'i, R> {
/// ```
#[inline]
pub fn match_string(mut self: Box<Self>, string: &str) -> ParseResult<Box<Self>> {
let token = ParsingToken::Sensitive {
token: String::from(string),
};
let start_position = self.position.pos();
if self.position.match_string(string) {
self.handle_token_parse_result(start_position, token, true);
let succeeded = self.position.match_string(string);
if self.parse_attempts.enabled {
let token = ParsingToken::Sensitive {
token: String::from(string),
};
self.handle_token_parse_result(start_position, token, succeeded);
}
if succeeded {
Ok(self)
} else {
self.handle_token_parse_result(start_position, token, false);
Err(self)
}
}
Expand Down Expand Up @@ -1053,15 +1087,17 @@ impl<'i, R: RuleType> ParserState<'i, R> {
/// ```
#[inline]
pub fn match_insensitive(mut self: Box<Self>, string: &str) -> ParseResult<Box<Self>> {
let token = ParsingToken::Insensitive {
token: String::from(string),
};
let start_position = self.position().pos();
if self.position.match_insensitive(string) {
self.handle_token_parse_result(start_position, token, true);
let start_position: usize = self.position().pos();
let succeeded = self.position.match_insensitive(string);
if self.parse_attempts.enabled {
let token = ParsingToken::Insensitive {
token: String::from(string),
};
self.handle_token_parse_result(start_position, token, succeeded);
}
if succeeded {
Ok(self)
} else {
self.handle_token_parse_result(start_position, token, false);
Err(self)
}
}
Expand Down Expand Up @@ -1093,16 +1129,18 @@ impl<'i, R: RuleType> ParserState<'i, R> {
/// ```
#[inline]
pub fn match_range(mut self: Box<Self>, range: Range<char>) -> ParseResult<Box<Self>> {
let start_position = self.position().pos();
let token = ParsingToken::Range {
start: range.start,
end: range.end,
};
let start_position = self.position().pos();
if self.position.match_range(range) {
self.handle_token_parse_result(start_position, token, true);
let succeeded = self.position.match_range(range);
if self.parse_attempts.enabled {
self.handle_token_parse_result(start_position, token, succeeded);
}
if succeeded {
Ok(self)
} else {
self.handle_token_parse_result(start_position, token, false);
Err(self)
}
}
Expand Down
6 changes: 3 additions & 3 deletions vm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "pest_vm"
description = "pest grammar virtual machine"
version = "2.7.9"
version = "2.7.10"
edition = "2021"
authors = ["Dragoș Tiselice <[email protected]>"]
homepage = "https://pest.rs/"
Expand All @@ -14,8 +14,8 @@ readme = "_README.md"
rust-version = "1.61"

[dependencies]
pest = { path = "../pest", version = "2.7.9" }
pest_meta = { path = "../meta", version = "2.7.9" }
pest = { path = "../pest", version = "2.7.10" }
pest_meta = { path = "../meta", version = "2.7.10" }

[features]
grammar-extras = ["pest_meta/grammar-extras"]
Loading