Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
9 changes: 9 additions & 0 deletions src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,15 @@ pub fn lex<'src>(input: &'src str) -> (Option<Tokens<'src>>, Vec<crate::error::R
)
}

/// Checks whether a given string is a keyword.
#[cfg(feature = "arbitrary")]
pub fn is_keyword(s: &str) -> bool {
matches!(
s,
"fn" | "let" | "type" | "mod" | "const" | "match" | "true" | "false"
)
}

#[cfg(test)]
mod tests {
use chumsky::error::Rich;
Expand Down
13 changes: 8 additions & 5 deletions src/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ macro_rules! wrapped_string {
/// Implementation of [`arbitrary::Arbitrary`] for wrapped string types,
/// such that strings of 1 to 10 letters `a` to `z` are generated.
///
/// The space of lowercase letter strings includes values that are invalid
/// according to the grammar of the particular string type. For instance,
/// keywords are reserved. However, this should not affect fuzzing.
/// The space of lowercase letter strings includes reserved keywords,
/// which cannot be used as identifiers. To ensure valid grammar
/// for fuzzing, any generated keywords are padded with the `_`.
macro_rules! impl_arbitrary_lowercase_alpha {
($wrapper:ident) => {
#[cfg(feature = "arbitrary")]
Expand All @@ -61,6 +61,9 @@ macro_rules! impl_arbitrary_lowercase_alpha {
let offset = u.int_in_range(0..=25)?;
string.push((b'a' + offset) as char)
}
if crate::lexer::is_keyword(string.as_str()) {
string.push('_');
}
Ok(Self::from_str_unchecked(string.as_str()))
}
}
Expand Down Expand Up @@ -103,7 +106,7 @@ impl<'a> arbitrary::Arbitrary<'a> for FunctionName {
let offset = u.int_in_range(0..=25)?;
string.push((b'a' + offset) as char)
}
if RESERVED_NAMES.contains(&string.as_str()) {
if RESERVED_NAMES.contains(&string.as_str()) || crate::lexer::is_keyword(string.as_str()) {
string.push('_');
}

Expand Down Expand Up @@ -202,7 +205,7 @@ impl<'a> arbitrary::Arbitrary<'a> for AliasName {
let offset = u.int_in_range(0..=25)?;
string.push((b'a' + offset) as char)
}
if RESERVED_NAMES.contains(&string.as_str()) {
if RESERVED_NAMES.contains(&string.as_str()) || crate::lexer::is_keyword(string.as_str()) {
string.push('_');
}

Expand Down
Loading